<html>

<head>
<title>Deprecating Vestigial Library Parts in C++17</title>
<style type="text/css">
  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;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
</style>
</head>

<body>
<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">D0174R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2016-02-15</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr><tr>
  <td align="left">Audience:</td>
  <td align="left">Library Evolution Working Group</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Deprecating Vestigial Library Parts in C++17</h1>

<h2>Table of Contents</h2>
<ul>
<li><a href="#rev.hist">Revision History</a></li>
  <ul>
  <li><a href="#rev.0">Revision 0</a></li>
  </ul>
<li><a href="#1.0">Introduction</a></li>
<li><a href="#2.0">Recommendations for Deprecation</a></li>
  <ul>
  <li><a href="#2.1">Deprecate <tt>std::iterator</tt></a></li>
  <li><a href="#2.2">Deprecate <tt>value_compare</tt> Predicates</a></li>
  <li><a href="#2.3">Deprecate algorithms taking half an input range</a></li>
  <li><a href="#2.4">Deprecate the Redundant Members of <tt>std::allocator</tt></a></li>
  </ul>
<li><a href="#3.0">Additional Candidates</a></li>
  <ul>
  <li><a href="#3.1">Reconsider <tt>vector&lt;bool&gt;</tt> Partial Specialization</a></li>
  <li><a href="#3.2">Reconsider <tt>is_literal</tt>  Trait</a></li>
  <li><a href="#3.3">Reconsider the Temporary Buffer APIs</a></li>
  <li><a href="#3.4">Reconsider raw storage iterators</a></li>
  </ul>
<li><a href="#4.0">Proposed Wording</a></li>
  <ul>
  <li><a href="#4.0.1">20.7.2 Header &lt;memory&gt; synopsis [memory.syn]</li>
  <li><a href="#4.1">20.7.9 The default allocator [default.allocator]</a></li>
  <li><a href="#4.2">20.7.9.1 allocator members [allocator.members]</a></li>
  <li><a href="#4.3">23.2.4 Associative containers [associative.reqmts]</a></li>
  <li><a href="#4.4">23.4.4 Class template <tt>map</tt> [map]</a></li>
  <li><a href="#4.4.1">23.4.4.1 Class template <tt>map</tt> overview [map.overview]</a></li>
  <li><a href="#4.5">23.4.5 Class template <tt>multimap</tt> [multimap]</a></li>
  <li><a href="#4.5.1">23.4.5.1 Class template <tt>multimap</tt> overview [multimap.overview]</a></li>
  <li><a href="#4.6">23.4.6 Class template <tt>set</tt> [set]</a></li>
  <li><a href="#4.6.1">23.4.6.1 Class template <tt>set</tt> overview [set.overview]</a></li>
  <li><a href="#4.7">23.4.7 Class template <tt>multiset</tt> [multiset]</a></li>
  <li><a href="#4.7.1">23.4.7.1 Class template <tt>multiset</tt> overview [multiset.overview]</a></li>
  <li><a href="#4.8">24.3 Header <tt>&lt;iterator&gt;</tt> synopsis [iterator.synopsis]</a></li>
  <li><a href="#4.9">24.4.2 Basic iterator [iterator.basic]</a></li>
  <li><a href="#4.10">25 Algorithms library [algorithms]</a></li>
  <li><a href="#4.10.1">25.1 General [algorithms.general]</a></li>
  <li><a href="#4.11">25.2.10 Mismatch [mismatch]</a></li>
  <li><a href="#4.11">25.2.10 Mismatch [mismatch]</a></li>
  <li><a href="#4.12">25.2.11 Equal [alg.equal]</a></li>
  <li><a href="#4.13">25.2.12 Is permutation [alg.is_permutation]</a></li>
  <li><a href="#4.14">D.w The default allocator [depr.default.allocator]</a></li>
  <li><a href="#4.15">D.x Value Comparators for Associative Containers [depr.container.assoc.value_compare]</a></li>
  <li><a href="#4.16">D.y Basic iterator [depr.iterator.basic]</a></li>
  <li><a href="#4.17">D.z Algorithms with Partially Formed Ranges [depr.algorithm.partial.range]</a></li>
  </ul>
<li><a href="#5.0">Acknowledgements</a></li>
<li><a href="#6.0">References</a></li>
</ul>


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

<h3><a name="rev.0">Revision 0</a></h3>
<p>
Original version of the paper for the 2016 pre-Jacksonville mailing.
</p>


<h2><a name="1.0">Introduction</a></h2>
<p>
A number of features of the C++ Standard library have been surpassed by
additions over the years, or we have learned do not serve their intended
purpose as well as originally expected.  This paper proposed deprecating
features where better, simpler, or clearer options are available.
</p>


<h2><a name="2.0">Recommendations for Deprecation</a></h2>
<p>
There is likely to be a reasonable amount of user code using all of the feature
below in production today, so it would be premature to remove them from the
standard.  However, with best best practice advancing and superior or clearer
options available within the standard itself, now would be a good time to
deprecate these features, directing users to the preferred alternative instead. 
</p>


<h2><a name="2.1">Deprecate <tt>std::iterator</tt></a></h2>
<p>
As an aid to writing iterator classes, the original standard library supplied
the <tt>iterator</tt> class template to automate the declaration of the five
typedefs expected of every iterator by <tt>iterator_traits</tt>.  This was then
used in the library itself, for instance in the specification of
<tt>std::ostream_iterator</tt>:
</p>
<blockquote><pre>
template &lt;class T, class charT = char, class traits = char_traits&lt;charT&gt; &gt;
class ostream_iterator:
  public iterator&lt;output_iterator_tag, void, void, void, void&gt;;
</pre></blockquote>
<p>
The long sequence of <tt>void</tt> arguments is much less clear to the reader
than simply providing the expected typedefs in the class definition itself,
which is the approach taken by the current working draft, following the pattern
set in C++14 where we deprecated the derivation throughout the library of
functors from <tt>unary_function</tt> and <tt>binary_function</tt>.
</p>
<p>
In addition to the reduced clarity, the <tt>iterator</tt> template also lays a
trap for the unwary, as in typical usage it will be a dependent base class,
which means it will not be looking into during name lookup from within the
class or its member functions.  This leads to surprised users trying to
understand why the following simple usage does not work:
</p>
</p>
<blockquote><pre>
#include &lt;iterator&gt;

template &lt;typename T&gt;
struct MyIterator : std::iterator&lt;std::random_access_iterator_tag, T&gt; {
   value_type data;  <i>// Error: value_type is not found by name lookup</i> 

   <i>// ... implementations details elided ...</i>
};
</pre></blockquote>
<p>
The reason of clarity alone was sufficient to persuade the LWG to update the
standard library specification to no longer mandate the standard iterator
adapators as deriving from <tt>std::iterator</tt>, so there is no further use
of this template within the standard itself.  Therefore, it looks like a strong
candidate for deprecation.
</p>


<h3><a name="2.2">Deprecate <tt>value_compare</tt> predicates</a></h3>
<p>
The standard containers <tt>map</tt> and <tt>multimap</tt> both contain an
identical class template <tt>value_compare</tt> that is a functor which can be
used to determine the relative order of two elements in that container.  These
are provided as elements in a map are ordered by only the key value, rather
than the whole value, so the predicate supplied to the container compares the
key type, not the actual element type.
</p>
<p>
In practice these functors are not used by the containers, as they are often
required to compare keys with values for elements that have not yet been
inserted into the map, and may not have been created as a <tt>pair</tt> yet.
Meanwhile, the cost of having a nested class type, rather than an alias to a
functor with the same behavior, means that every associative container with a
different allocator has an identical copy of this class, but with a different
name mangling so that the duplicate functionality cannot be elided or merged.
The class name itself will have a longer mangling than necessary, which would
add up if these functors were genuinely useful and saw much use in practice.
</p>
<p>
However, it is not clear that these functors do see much actual use.  For
example, a quick search with Google Code search while preparing this paper
turned up 29 hits, which were all standard library implementations, or test
drivers for standard library implementations, and a similar result for the
<tt>value_comp()</tt> function that returns an appropriately constructed
functor from the container for the client to use.
</p>
<p>
This paper recommends deprecating the <tt>value_compare</tt> member classes of
the associative containers, and moving their declarations and definitions to
Annex D, just as the old iostreams members were handled in the original 1998
standard.  It further recommends making it unspecified whether these members
are provided as member-classes, per the text of the standard, or as aliases to
a class with the same interface, allowing, but not requiring, vendors to choose
to provide these members in a less redundant (but ABI-breaking) manner.
</p>


<h3><a name="2.3">Deprecate algorithms taking half an input range</a></h3>
<p>
The standard library has several algorithms that read from two ranges in order
to determine their result.  In most cases, the original C++98 standard fully
specified the first range with a pair of iterators, and supplied only the first
iterator for the second range, with a narrow contract requirement that the
second range be at least as large as the first.  For the C++14 standard, these
algorithms were overloaded with a second form where the second range is also
fully specified by a pair of iterators, partly so that the length of the second
sequence can be taken into account (when it is shorter), and partly because
this form is less liable to misuse leading to buffer overruns and other
security risks.  See
<b><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3671.html">N3671</a>
Making non-modifying sequence operations more robust</b> for more details.
</p>
<p>
Given the security risks associated with the original algorithms, this paper
recommends deprecating the form of any algorithm where a second input range is
specified by only one iterator.  Note that algorithms using a single iterator
for an output range continue to be supported, as there is no (standard) way to
specify the end of an output iteration sequence, such as defined by an
<tt>std::ostream_iterator</tt>.
</p>

<h3><a name="2.4">Deprecate the redundant members of <tt>std::allocator</tt></a></h3>
<p>
Many members of <tt>std::allocator</tt> redundantly duplicate behavior that is
otherwise produced by <tt>std::allocator_traits&lt;allocator&lt;T&gt;&gt;</tt>,
and could safely be removed to simplify this class.  Further,
<tt>addressof</tt> as a free function supersedes
<tt>std::allocator&lt;T&gt;::address</tt> which requires an <tt>allocator</tt>
object of the right type.  Finally, the <tt>reference</tt> type aliases were
initially provided as an expected means for extension with other allocators,
but turned out to not serve a useful purpose when we specified the allocator
requirements (17.6.3.5 [allocator.requirements]).
</p>
<p>
While we cannot remove these members without breaking backwards compatibility
with code that explicitly used this allocator type, we should not be
recommending their continued use.  If a type wants to support generic
allocators, it should access the allocator's functionality through
<tt>allocator_traits</tt> rather than directly accessing the allocator's
members - otherwise it will not properly support allocators that rely on the
traits to synthesize the default behaviors.  Similarly, if a user does not
intend to support generic allocators, then it is much simpler to directly
invoke <tt>new</tt>, <tt>delete</tt>, and assume the other properties of
<tt>std::allocator</tt> such as pointer-types directly.
</p>
<p>
While the <tt>is_always_equal</tt> trait might be implicitly synthesized from
the trait <tt>is_empty_v&lt;allocator&lt;T&gt;&gt;</tt>, there appears to be no
specified guarantee that <tt>std::allocator</tt> specializations be empty
classes (although this is widely expected) so the trait remains explicitly
specialized to provide the necessary guarantee, even for implementations that
choose to add some data to <tt>std::allocator</tt> for debug, profiling, or
other purposes.
</p>
<p>
Similarly, <tt>std::allocator&lt;void&gt;</tt> is defined so that various
template rebinding tricks could work in the original C++98 library, but it is
not an actual allocator, as it lacks both <tt>allocate</tt> and
<tt>deallocate</tt> member functions, which cannot be synthesized by default
from <tt>allocator_traits</tt>.  That need went away with C++11 and the
<tt>void_pointer</tt> and <tt>const_void_pointer</tt> type aliases in
<tt>allocator_traits</tt>.  However, we continue to specify it in order to
avoid breaking old code that has not yet been upgraded to support generic
allocators, per C++11.
</p>
<p>
This paper recommends deprecating <tt>std::allocator&lt;void&gt;</tt> and the
redundant members of the <tt>std::allocator</tt> class template, and moving
their declarations and definitions to Annex D, just as the old iostreams
members were handled in the original 1998 standard.
</p>
<p>
One potential concern is whether removing these members in the future might
cause a compile-time performance regression, if the library is expected to
deduce the default behavior in each case.  The proposed Zombie Names clause
from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0090r0.htm">P0090R0</a>
and incorporated in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0005r3.htm">P0005R3</a>
would allow vendors to retain these names indefinitely, if that were a concern.
However, the optimal (compile-time) solution for the library implementation is
to provide a partial specialization for
<tt>std::allocator_traits&lt;std::allocator&lt;T&gt;&gt;</tt>, and so entirely
avoid the cost of evaluating complex template machinery for the default
allocator in the standard library.
</p>
<p>
It was also observed, while writing this paper, that the allocator propagation
traits for <tt>std::allocator&lt;void&gt;</tt> do not match those for
<tt>std::allocator&lt;T&gt;</tt>.  It was decided not to provide a drive-by
fix, as <tt>std::allocator&lt;void&gt;</tt> is not a true allocator, and so
should not end up in code relying on those traits.  If the desision is made not
to deprecate this specialization though, it could be worth revisitting the
issue, just to address consistency and a lack of surprise.
</p>

<h2><a name="3.0">Additional Candidates</a></h2>
<p>
Several additional aspects of the library were looked at, but decided against a
recommendation for deprecation at this point.  They are listed here, with
rationale, in case others are more motivated.  With appropriate additions to
the standard, these may become stronger deprecation candidates for the next
standard.
</p>

<p>
If members of the Library Working Groups would like to see any of these
additional libraries deprecated, the author is happy to extend the proposal,
but feels that they go beyond the remit of this paper deprecating only features
where a preferable alternative is already available in the standard.
</p>

<h3><a name="3.1">Reconsider <tt>vector&lt;bool&gt;</tt> Partial Specialization</a></h3>
<p>
There has been a long history of the <tt>bool</tt> partial specialization
of <tt>std::vector</tt> not satisfying the container requirements, and in
particular, its iterators not satisfying the requirements of a random access
iterator.  A previous attempt to deprecate this container was rejected for C++11,
<a href=http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2204>N2204</a>.
</p>

<p>
One of the reasons for rejection is that it is not clear what it would mean to
deprecate a particular specialization of a template.  That could be addressed
with careful wording.  The larger issue is that the (packed) specialization of
<tt>vector&lt;bool&gt;</tt> offers an important optimization that clients of
the standard library genuinely seek, but would not longer be available.  It is
unlikely that we would be able to deprecate this part of the standard until a
replacement facility is proposed and accepted, such as
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2050">N2050</a>.
Unfortunately, there are no such revised proposals currently being offered to
the Library Evolution Working Group.
</p>

<h3><a name="3.2">Reconsider <tt>is_literal</tt> Trait</a></h3>
<p>
The <tt>is_literal</tt> type trait offers negligible value to generic code, as
what is really needed is the ability to know that a specific construction would
produce constant initialization.  The core term of a <i>literal type</i> having
at least one <tt>constexpr</tt> constructor is too weak to be used
meaningfully.
</p>

<p>
However, the (already implemented) trait does no harm, and allows compile-time
introspection for which core-language type-categories a given template
parameter might satisfy.  Until the Core Working Group retire the notion of a
literal type, the corresponding library trait should be preserved.
</p>

<p>
One way forward would be to write a paper proposing to remove the term from the
core language while deprecating/removing the type trait, but the author of this
paper is not (yet) sufficiently motivated to author such a proposal.
</p>


<h3><a name="3.3">Reconsider the Temporary Buffer APIs</a></h3>
<p>
Library clause 20.7.11 <b>[temporary.buffer]</b> provides an API intended to
efficiently create a <em>small</em> ammount of additional storage for local,
short-term use.  The inspiration behind the API is to use some magic to create
a tiny buffer on the stack.
</p>

<p>
This API would be considered an incomplete thought were it proposed today.  As
a functional API it lacks exception safety if the function allocating the
buffer leaks, yet we offer no RAII-like wrappers to promote safe use.
</p>

<p>
It has been suggested that all current implementation of this API actually do
not perform a more efficient allocation than the regular <tt>new</tt> operator,
and, if that is genuinely the case, we should seriously consider deprecating
this facility.  Otherwise, we should probably complete the design with an
appropriate guard/wrapper class, and encourage vendors to deliver on missed
optimization opportunities.
</p>

<p>
It is possible the need for this API could be overtaken by delivering on a
genuine C++ API or data structure for allocating off the stack, such as was
proposed by <tt>std::dynarray</tt> in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3662">N3662</a>.
However, the Evolution Working Group has not been keen on further work in this
direction, and the Arrays TS appears to have stalled, if not abandoned
entirely.
</p>

<h3><a name="3.4">Reconsider raw storage iterators</a></h3>
<p>
Like the temporary buffer API, the <tt>raw_storage_iterator</tt> (20.7.10
<b>[storage.iterator]</b>) and uninitialized algorithms (20.7.12
<b>[specialized.algorithms]</b>) are incomplete thoughts, although they
appeared complete at the time of adoption.
</p>

<p>
One obvious shortcoming of the iterator adapter is that it could easily query
the type of element the adapated iterator is prepared to construct via
<tt>iterator_traits</tt> and provide a default template argument for the second
parameter, simplifying use.  That no such proposal has come forward in almost
20 years suggests that this is not a widely used component.  Similarly, a
type-deducing factory function would be a natural extension, especially with
the advent of <tt>auto</tt> in C++11, yet no such proposal has materialized.
</p>

<p>
A deeper concern arises from the completion of allocator support in C++11.
There is now a common requirement that construting an object in a region of
allocated memory should invoke the <tt>construct</tt> method of the
corresponding allocator.  This is not possible with the current iterator, and
undermines its use as an implementation detail in users writing generic
containers.  However, no-one seems motivated to invest the time in proposing an
allocator-aware raw storage iterator, nor adding allocator-awareness to the
uninitialized memory algorithms.
</p>

<p>
Without a clear alternative to replace them, there is no clear deprecation path
other than simply looking to drop support for the whole idea in some future
standard.  That goes beyond the intent of this paper.
</p>


<h2><a name="4.0">Proposed Wording</a></h2>
<p>
Amend existing library clauses as below:
</p>
<blockquote>

<h3><a name="4.0.1">20.7.2 Header &lt;memory&gt; synopsis [memory.syn]</h3>
<blockquote><pre>
namespace std {
  <i>// ...</i>

  <i>// 20.7.9, the default allocator:</i>
  template &lt;class T&gt; class allocator;
  <del>template &lt;&gt; class allocator&lt;void&gt;;</del>
  template &lt;class T, class U&gt;
    bool operator==(const allocator&lt;T&gt;&amp;, const allocator&lt;U&gt;&amp;) noexcept;
  template &lt;class T, class U&gt;
    bool operator!=(const allocator&lt;T&gt;&amp;, const allocator&lt;U&gt;&amp;) noexcept;

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

<h3><a name="4.1">20.7.9 The default allocator [default.allocator]</a></h3>
<ol>
<li>All specializations of the default allocator satisfy the allocator completeness requirements 17.6.3.5.1.</li>
<blockquote><pre>
namespace std {
  <del>template &lt;class T&gt; class allocator;</del>

  <del>// specialize for void:</del>
  <del>template &lt;&gt; class allocator&lt;void&gt; {</del>
  <del>public:</del>
    <del>typedef void* pointer;</del>
    <del>typedef const void* const_pointer;</del>
    <del><i>// reference-to-void members are impossible.</i></del>
    <del>typedef void value_type;</del>
    <del>template &lt;class U&gt; struct rebind { typedef allocator&lt;U&gt; other; };</del>
  <del>};</del>

  template &lt;class T&gt; class allocator {
   public:
    <del>typedef size_t    size_type;</del>
    <del>typedef ptrdiff_t difference_type;</del>
    <del>typedef T*        pointer;</del>
    <del>typedef const T*  const_pointer;</del>
    <del>typedef T&amp;        reference;</del>
    <del>typedef const T&amp;  const_reference;</del>
    typedef T         value_type;
    <del>template &lt;class U&gt; struct rebind { typedef allocator&lt;U&gt; other; };</del>
    typedef true_type propagate_on_container_move_assignment;
    typedef true_type is_always_equal;
    allocator() noexcept;
    allocator(const allocator&amp;) noexcept;
    template &lt;class U&gt; allocator(const allocator&lt;U&gt;&amp;) noexcept;
    ~allocator();
    <del>pointer address(reference x) const noexcept;</del>
    <del>const_pointer address(const_reference x) const noexcept;</del>
    <del>pointer</del><ins>T*</ins> allocate(
      size_t<del>ype</del>, <del>allocator&lt;void&gt;::const_pointer</del><ins>const void*</ins> hint = 0);
    void deallocate(<del>pointer</del><ins>T*</ins> p, size_t<del>ype</del> n);
    size_t<del>ype</del> max_size() const noexcept;
    <del>template&lt;class U, class... Args&gt;</del>
      <del>void construct(U* p, Args&amp;&amp;... args);</del>
    <del>template &lt;class U&gt;</del>
      <del>void destroy(U* p);</del>
  };
}
</pre></blockquote>
</ol>
<h3><a name="4.2">20.7.9.1 allocator members [allocator.members]</a></h3>
<ol>
<li>
Except for the destructor, member functions of the default allocator shall not
introduce data races (1.10) as a result of concurrent calls to those member
functions from different threads. Calls to these functions that allocate or
deallocate a particular unit of storage shall occur in a single total order,
and each such deallocation call shall happen before the next allocation (if
any) in this order.
</li>
<pre><del>pointer address(reference x) const noexcept;</del></pre>
<li><del>
<i>Returns:</i> The actual address of the object referenced by <tt>x</tt>, even
in the presence of an overloaded <tt>operator&amp;</tt>.
</del></li>
<pre><del>const_pointer address(const_reference x) const noexcept;</del></pre>
<li><del>
<i>Returns:</i> The actual address of the object referenced by <tt>x</tt>, even
in the presence of an overloaded <tt>operator&amp;</tt>.
</del></li>
<pre><del>pointer</del><ins>T*</ins> allocate(size_type n, <del>allocator<void>::const_pointer</del><ins>const void*</ins> hint = 0);</pre>
<li>
[ <i>Note:</i> In a container member function, the address of an adjacent
element is often a good choice to pass for the hint argument. <i>- end note</i>
]
</li>
<li>
<i>Returns:</i> A pointer to the initial element of an array of storage of size
<tt>n * sizeof(T)</tt>, aligned appropriately for objects of type <tt>T</tt>.
It is implementation-defined whether over-aligned types are supported (3.11).
</li>
<li>
<i>Remark:</i> the storage is obtained by calling
<tt>::operator new(std::size_t)</tt> (18.6.1), but it is unspecified when or
how often this function is called. The use of <tt>hint</tt> is unspecified, but
intended as an aid to locality if an implementation so desires.
</li>
<li>
<i>Throws:</i> <tt>bad_alloc</tt> if the storage cannot be obtained.
</li>
<pre>void deallocate(<del>pointer</del><ins>T*</ins> p, size_type n);</pre>
<li>
<i>Requires:</i> <tt>p</tt> shall be a pointer value obtained from
<tt>allocate()</tt>.  <tt>n</tt> shall equal the value passed as the first
argument to the invocation of allocate which returned <tt>p</tt>.
</li>
<li>
<i>Effects:</i> Deallocates the storage referenced by <tt>p</tt>.
</li>
<li>
<i>Remarks:</i> Uses <tt>::operator delete(void*, std::size_t)</tt> (18.6.1),
but it is unspecified when this function is called.
</li>
<pre>size_type max_size() const noexcept;</pre>
<li>
<i>Returns:</i> The largest value <tt>N</tt> for which the call
<tt>allocate(N,0)</tt> might succeed.
</li>
<pre>
<del>template &lt;class U, class... Args&gt;</del>
  <del>void construct(U* p, Args&amp;&amp;... args);</del>
</pre>
<li><del>
<i>Effects:</i> <tt>::new((void *)p) U(std::forward&lt;Args&gt;(args)...)</tt>
</del></li>
<pre>
<del>template &lt;class U&gt;</del>
  <del>void destroy(U* p);</del>
</pre>
<li><del>
<i>Effects:</i> <tt>p-&gt;~U()</tt>
</del></li>
</ol>

</blockquote>
<p>Delete two rows from Table 101 - Associative container requirements (in addition to container)</p>
<blockquote>

<h3><a name="4.3">23.2.4 Associative containers [associative.reqmts]</a></h3>
<table border="1" cellpadding="0" cellspacing="0">
<tr>
  <td><b>Expression</b></td>
  <td><b>Return type</b></td>
  <td><b>Assertion/note/pre-/post-condition</b></td>
  <td><b>Complexity</b></td>
</tr>
<tr>
  <td><tt></tt></td>
  <td><tt></tt></td>
  <td><i>... rows elided ...</i></td>
  <td></td>
</tr>
<tr>
  <td><tt>key_compare</tt></td>
  <td><tt>Compare</tt></td>
  <td>defaults to <tt>less&lt;key_type&gt;</td>
  <td>compile time</td>
</tr>
<tr>
  <td><del><tt>value_compare</tt></del></td>
  <td><del>a binary predicate type</del></td>
  <td><del>
    is the same as <tt>key_compare</tt> for <tt>set</tt> and <tt>multiset</tt>;
    is an ordering relation on pairs induced by the first component (i.e.,
    <tt>Key</tt>) for <tt>map</tt> and <tt>multimap</tt>.
  </del></td>
  <td><del>compile time</del></td>
</tr>
<tr>
  <td><tt></tt></td>
  <td><tt></tt></td>
  <td><i>... rows elided ...</i></td>
  <td></td>
</tr>
<tr>
  <td><tt>a.key_comp()</tt></td>
  <td><tt>X::key_compare</tt></td>
  <td>returns the comparison objects out of which <tt>a</tt> was constructed</td>
  <td>constant</td>
</tr>
<tr>
  <td><del><tt>a.value_comp()</tt></del></td>
  <td><del><tt>X::value_compare</tt></del></td>
  <td><del>
    returns an object of <tt>value_compare</tt> constructed out of the comparison
    object
  </del></td>
  <td><del>constant</del></td>
</tr>
<tr>
  <td><tt></tt></td>
  <td><tt></tt></td>
  <td><i>... rows elided ...</i></td>
  <td></td>
</tr>
</table>

<h3><a name="4.4">23.4.4 Class template <tt>map</tt>              [map]</a></h3>
<h3><a name="4.4.1">23.4.4.1 Class template <tt>map</tt> overview   [map.overview]</a></h3>
<blockquote><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>
    <i>// details elided...</i>

    <del>class value_compare {</del>
    <del>friend class map;</del>
    <del>protected:</del>
      <del>Compare comp;</del>
      <del>value_compare(Compare c) : comp(c) {}</del>
    <del>public:</del>
      <del>typedef bool result_type;</del>
      <del>typedef value_type first_argument_type;</del>
      <del>typedef value_type second_argument_type;</del>
      <del>bool operator()(const value_type&amp; x, const value_type&amp; y) const {</del>
        <del>return comp(x.first, y.first);</del>
      <del>}</del>
    <del>};</del>

    <i>// 23.4.4.2, construct/copy/destroy:</i>
    <i>// details elided...</i>

    <i>// observers:</i>
    key_compare key_comp() const;
    <del>value_compare value_comp() const;</del>

    <i>// remaining details elided...</i>
  };
}
</pre></blockquote>


<h3><a name="4.5">23.4.5 Class template <tt>multimap</tt>              [multimap]</a></h3>
<h3><a name="4.5.1">23.4.5.1 Class template <tt>multimap</tt> overview   [multimap.overview]</a></h3>
<blockquote><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>
    <i>// details elided...</i>

    <del>class value_compare {</del>
    <del>friend class multimap;</del>
    <del>protected:</del>
      <del>Compare comp;</del>
      <del>value_compare(Compare c) : comp(c) {}</del>
    <del>public:</del>
      <del>typedef bool result_type;</del>
      <del>typedef value_type first_argument_type;</del>
      <del>typedef value_type second_argument_type;</del>
      <del>bool operator()(const value_type&amp; x, const value_type&amp; y) const {</del>
        <del>return comp(x.first, y.first);</del>
      <del>}</del>
    <del>};</del>

    <i>// construct/copy/destroy:</i>
    <i>// details elided...</i>

    <i>// observers:</i>
    key_compare key_comp() const;
    <del>value_compare value_comp() const;</del>

    <i>// remaining details elided...</i>
  };
}
</pre></blockquote>

<h3><a name="4.6">23.4.6 Class template <tt>set</tt>              [set]</a></h3>
<h3><a name="4.6.1">23.4.6.1 Class template <tt>set</tt> overview   [set.overview]</a></h3>
<blockquote><pre>
namespace std {
  template &lt;class Key, class Compare = less&lt;Key&gt;,
            class Allocator = allocator&lt;Key&gt; &gt;
  class set {
  public:
    <i>// types</i>
    typedef Key               key_type;
    typedef Key               value_type;
    typedef Compare           key_compare;
    <del>typedef Compare           value_compare;</del>
    <i>// details elided...</i>

    <i>// 23.4.6.2, construct/copy/destroy:</i>
    <i>// details elided...</i>

    <i>// observers:</i>
    key_compare key_comp() const;
    <del>value_compare value_comp() const;</del>

    <i>// remaining details elided...</i>
  };
}
</pre></blockquote>

<h3><a name="4.7">23.4.7 Class template <tt>multiset</tt>              [multiset]</a></h3>
<h3><a name="4.7.1">23.4.7.1 Class template <tt>multiset</tt> overview   [multiset.overview]</a></h3>
<blockquote><pre>
namespace std {
  template &lt;class Key, class Compare = less&lt;Key&gt;,
            class Allocator = allocator&lt;Key&gt; &gt;
  class multiset {
  public:
    <i>// types</i>
    typedef Key               key_type;
    typedef Key               value_type;
    typedef Compare           key_compare;
    <del>typedef Compare           value_compare;</del>
    <i>// details elided...</i>

    <i>// construct/copy/destroy:</i>
    <i>// details elided...</i>

    <i>// observers:</i>
    key_compare key_comp() const;
    <del>value_compare value_comp() const;</del>

    <i>// remaining details elided...</i>
  };
}
</pre></blockquote>



<h3><a name="4.8">24.3 Header <tt>&lt;iterator&gt;</tt> synopsis [iterator.synopsis]</a></h3>
<blockquote><pre>
namespace std {
  <i>// 24.4, primitives:</i>
  template&lt;class Iterator&gt; struct iterator_traits;
  template&lt;class T&gt; struct iterator_traits&lt;T*&gt;;

  <del>template&lt;class Category, class T, class Distance = ptrdiff_t,</del>
         <del>class Pointer = T*, class Reference = T&amp;&gt; struct iterator;</del>

  <i>// Rest of header elided...</i>
}
</pre></blockquote>

<h3><a name="4.9"><del>24.4.2 Basic iterator [iterator.basic]</del></a></h3>
<ol>
<li><del>
The <tt>iterator</tt> template may be used as a base class to ease the definition of required types for new iterators.
</del></li>
<blockquote><pre>
<del>namespace std {</del>
  <del>template&lt;class Category, class T, class Distance = ptrdiff_t,</del>
    <del>class Pointer = T*, class Reference = T&amp;&gt;</del>
  <del>struct iterator {</del>
    <del>typedef T         value_type;</del>
    <del>typedef Distance  difference_type;</del>
    <del>typedef Pointer   pointer;</del>
    <del>typedef Reference reference;</del>
    <del>typedef Category  iterator_category;</del>
  <del>};</del>
<del>}</del>
</pre></blockquote>
</ol>

<h3><a name="4.10">25 Algorithms library [algorithms]</a></h3>
<h4><a name="4.10.1">25.1 General [algorithms.general]</a></h4>
<h5>Header &lt;algorithm&gt; synopsis</h5>
<blockquote><pre>
#include &lt;initializer_list&gt;

namespace std {
<blockquote><i>// 25.2, non-modifying sequence operations:</i>

<i>// ... several declarations omitted for brevity</i>

<del>template&lt;class InputIterator1, class InputIterator2&gt;</del>
  <del>pair&lt;InputIterator1, InputIterator2&gt;</del>
    <del>mismatch(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2);</del>
<del>template</del>
 <del>&lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</del>
  <del>pair&lt;InputIterator1, InputIterator2&gt;</del>
    <del>mismatch(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2, BinaryPredicate pred);</del>

template&lt;class InputIterator1, class InputIterator2&gt;
  pair&lt;InputIterator1, InputIterator2&gt;
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2);
template
 &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;
  pair&lt;InputIterator1, InputIterator2&gt;
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2,
             BinaryPredicate pred);

<del>template&lt;class InputIterator1, class InputIterator2&gt;</del>
  <del>bool equal(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2);</del>
<del>template</del>
<del>&lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</del>
  <del>bool equal(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2, BinaryPredicate pred);</del>

template&lt;class InputIterator1, class InputIterator2&gt;
  bool equal(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2);

template
 &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;
  bool equal(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2,
             BinaryPredicate pred);

<del>template&lt;class ForwardIterator1, class ForwardIterator2&gt;</del>
  <del>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</del>
                      <del>ForwardIterator2 first2);</del>
<del>template&lt;class ForwardIterator1, class ForwardIterator2,</del>
                 <del>class BinaryPredicate&gt;</del>
  <del>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</del>
                      <del>ForwardIterator2 first2, BinaryPredicate pred);</del>

template&lt;class ForwardIterator1, class ForwardIterator2&gt;
  bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                      ForwardIterator2 first2, ForwardIterator2 last2);

template&lt;class ForwardIterator1, class ForwardIterator2,
                    class BinaryPredicate&gt;
  bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                      ForwardIterator2 first2, ForwardIterator2 last2,
                      BinaryPredicate pred);

<i>// ... many more declarations omitted for brevity</i>
</blockquote>}
</pre></blockquote>

<h3><a name="4.11">25.2.10 Mismatch [mismatch]</a></h3>

<blockquote><pre>
<del>template&lt;class InputIterator1, class InputIterator2&gt;</del>
  <del>pair&lt;InputIterator1, InputIterator2&gt;</del>
      <del>mismatch(InputIterator1 first1, InputIterator1 last1,</del>
               <del>InputIterator2 first2);</del>

<del>template&lt;class InputIterator1, class InputIterator2,</del>
          <del>class BinaryPredicate&gt;</del>
  <del>pair&lt;InputIterator1, InputIterator2&gt;</del>
      <del>mismatch(InputIterator1 first1, InputIterator1 last1,</del>
               <del>InputIterator2 first2, BinaryPredicate pred);</del>

template&lt;class InputIterator1, class InputIterator2&gt;
  pair&lt;InputIterator1, InputIterator2&gt;
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2);

template &lt;class InputIterator1, class InputIterator2,
           class BinaryPredicate&gt;
  pair&lt;InputIterator1, InputIterator2&gt;
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2,
             BinaryPredicate pred);
</pre></blockquote>
<ol>
<li>
<del><i>Remarks:</i> If <tt>last2</tt> was not given in the argument list, it
denotes <tt>first2 + (last1 - first1)</tt> below.</del>

</li>
<li>
<i>Returns:</i> A pair of iterators <tt>i</tt> and <tt>j</tt> such that
<tt>j == first2 + (i - first1)</tt> and <tt>i</tt> is the first iterator in the
range <tt>[first1,last1)</tt> for which the following corresponding conditions hold:
<ol>
<li>— <tt>j</tt> is in the range <tt>[first2, last2)</tt>.</li>
<li>— <tt>!(*i == *(first2 + (i - first1)))</tt></li>
<li>— <tt>pred(*i, *(first2 + (i - first1))) == false</tt></li>
</ol>
Returns the pair <tt>first1 + min(last1 - first1, last2 - first2)</tt> and
<tt>first2 + min(last1 - first1, last2 - first2)</tt> if such an iterator <tt>i</tt>
is not found.
</li>
<li>
<i>Complexity:</i> At most <tt>min(last1 - first1, last2 - first2)</tt> applications of the corresponding predicate.
</li>
</ol>

<h3><a name="4.12">25.2.11 Equal [alg.equal]</a></h3>
<blockquote><pre>
<del>template&lt;class InputIterator1, class InputIterator2&gt;</del>
  <del>bool equal(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2);</del>

<del>template&lt;class InputIterator1, class InputIterator2,</del>
          <del>class BinaryPredicate&gt;</del>
  <del>bool equal(InputIterator1 first1, InputIterator1 last1,</del>
             <del>InputIterator2 first2, BinaryPredicate pred);</del>

template&lt;class InputIterator1, class InputIterator2&gt;
  bool equal(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, InputIterator2 last2);

template&lt;class InputIterator1, class InputIterator2,
           class BinaryPredicate&gt;
bool equal(InputIterator1 first1, InputIterator1 last1,
           InputIterator2 first2, InputIterator2 last2,
           BinaryPredicate pred);
</pre></blockquote>
<ol>
<li>
<del><i>Remarks:</i> If <tt>last2</tt> was not given in the argument list, it denotes
<tt>first2 + (last1 - first1)</tt> below.<del>
</li>
<li>
<i>Returns:</i> If <tt>last1 - first1 != last2 - first2</tt>, return <tt>false</tt>.
Otherwise return <tt>true</tt> if for every iterator <tt>i</tt> in the range
<tt>[first1,last1)</tt> the following corresponding conditions hold:
<tt>*i == *(first2 + (i - first1))</tt>,
<tt>pred(*i, *(first2 + (i - first1))) != false</tt>. Otherwise, returns <tt>false</tt>.
</li>
<li>
<i>Complexity:</i> No applications of the corresponding predicate if
<tt>InputIterator1</tt> and <tt>InputIterator2</tt> meet the requirements of random access
iterators and <tt>last1 - first1 != last2 - first2</tt>. Otherwise, at most
<tt>min(last1 - first1, last2 - first2)</tt> applications of the corresponding predicate.
</li>
</ol>
<blockquote><pre>
</pre></blockquote>

<h3><a name="4.13">25.2.12 Is permutation [alg.is_permutation]</a></h3>
<blockquote><pre>
<del>template&lt;class ForwardIterator1, class ForwardIterator2&gt;</del>
  <del>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</del>
                      <del>ForwardIterator2 first2);</del>

<del>template&lt;class ForwardIterator1, class ForwardIterator2,</del>
                 <del>class BinaryPredicate&gt;</del>
  <del>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</del>
                      <del>ForwardIterator2 first2, BinaryPredicate pred);</del>

template&lt;class ForwardIterator1, class ForwardIterator2&gt;
  bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                      ForwardIterator2 first2, ForwardIterator2 last2);

template&lt;class ForwardIterator1, class ForwardIterator2,
                 class BinaryPredicate&gt;
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
                    ForwardIterator2 first2, ForwardIterator2 last2,
                    BinaryPredicate pred);
</pre></blockquote>
<ol>
<li>
<i>Requires:</i> <tt>ForwardIterator1</tt> and <tt>ForwardIterator2</tt> shall
have the same value type. The comparison function shall be an equivalence
relation.
</li>
<li>
<del><i>Remarks:</i> If <tt>last2</tt> was not given in the argument list, it
denotes <tt>first2 + (last1 - first1)</tt> below.</del>
</li>
<li>
<i>Returns:</i> If <tt>last1 - first1 != last2 - first2</tt>, return <tt>false</tt>.
Otherwise return <tt>true</tt> if there exists a permutation of the elements in the
range <tt>[first2,first2 + (last1 - first1))</tt>, beginning with
<tt>ForwardIterator2 begin</tt>, such that <tt>equal(first1, last1, begin)</tt>
returns <tt>true</tt> or <tt>equal(first1, last1, begin, pred)</tt> returns <tt>true</tt>;
otherwise, returns <tt>false</tt>.
</li>
<li>
<i>Complexity:</i> No applications of the corresponding predicate if <tt>ForwardIterator1</tt>
and <tt>ForwardIterator2</tt> meet the requirements of random access iterators and
<tt>last1 - first1 != last2 - first2</tt>. Otherwise, exactly <tt>distance(first1, last1)</tt>
applications of the corresponding predicate if <tt>equal( first1, last1, first2, last2)</tt>
would return <tt>true</tt> if <tt>pred</tt> was not given in the argument list or
<tt>equal(first1, last1, first2, last2, pred)</tt> would return <tt>true</tt> if <tt>pred</tt>
was given in the argument list; otherwise, at worst O(N<sup>2</sup>), where N has the value
<tt>distance(first1, last1)</tt>.
</li>
</ol>

</blockquote>


<p>
Insert new clauses into Annex D:
</p>
<blockquote>
<h3><a name="4.14"><ins>D.w The default allocator [depr.default.allocator]</ins></a></h3>
<ol>
<li><ins>The following members are defined in addition to those specified in Clause 20:</ins></li>
<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;&gt; class allocator&lt;void&gt; {</ins>
  <ins>public:</ins>
    <ins>typedef void* pointer;</ins>
    <ins>typedef const void* const_pointer;</ins>
    <ins><i>// reference-to-void members are impossible.</i></ins>
    <ins>typedef void value_type;</ins>
    <ins>template &lt;class U&gt; struct rebind { typedef allocator&lt;U&gt; other; };</ins>
  <ins>}</ins>;

  <ins>template &lt;class T&gt; class allocator {</ins>
  <ins>public:</ins>
    <ins>typedef size_t    size_type;</ins>
    <ins>typedef ptrdiff_t difference_type;</ins>
    <ins>typedef T*        pointer;</ins>
    <ins>typedef const T*  const_pointer;</ins>
    <ins>typedef T&amp;        reference;</ins>
    <ins>typedef const T&amp;  const_reference;</ins>
    <ins>template &lt;class U&gt; struct rebind { typedef allocator&lt;U&gt; other; };</ins>

    <ins>pointer address(reference x) const noexcept;</ins>
    <ins>const_pointer address(const_reference x) const noexcept;</ins>
    <ins>template&lt;class U, class... Args&gt;</ins>
      <ins>void construct(U* p, Args&amp;&amp;... args);</ins>
    <ins>template &lt;class U&gt;</ins>
      <ins>void destroy(U* p);</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>
<pre><ins>pointer address(reference x) const noexcept;</ins></pre>
<li><ins>
<i>Returns:</i> The actual address of the object referenced by <tt>x</tt>, even
in the presence of an overloaded <tt>operator&amp;</tt>.
</ins></li>
<pre><ins>const_pointer address(const_reference x) const noexcept;</ins></pre>
<li><ins>
<i>Returns:</i> The actual address of the object referenced by <tt>x</tt>, even
in the presence of an overloaded <tt>operator&amp;</tt>.
</ins></li>
<pre>
<ins>template &lt;class U, class... Args&gt;</ins>
  <ins>void construct(U* p, Args&amp;&amp;... args);</ins>
</pre>
<li><ins>
<i>Effects:</i> <tt>::new((void *)p) U(std::forward&lt;Args&gt;(args)...)</tt>
</ins></li>
<pre>
<ins>template &lt;class U&gt;</ins>
  <ins>void destroy(U* p);</ins>
</pre>
<li><ins>
<i>Effects:</i> <tt>p-&gt;~U()</tt>
</ins></li>
</ol>

<h3><a name="4.15"><ins>D.x Value Comparators for Associative Containers [depr.container.assoc.value_compare]</ins></a></h3>

<ol>
<li><ins>
The following member names are defined in addition to names specified in Clause
23.  It is unspecified whether the <tt>value_compare</tt> classes are provided
directly as member classes, or as aliases of classes with the same
specification:
</ins></li>
<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class Key, class T, class Compare = less&lt;Key&gt;,</ins>
            <ins>class Allocator = allocator&lt;pair&lt;const Key, T&gt; &gt; &gt;</ins>
  <ins>class map {</ins>
  <ins>public:</ins>
    <ins>class value_compare {</ins>
    <ins>friend class map;</ins>
    <ins>protected:</ins>
      <ins>Compare comp;</ins>
      <ins>value_compare(Compare c) : comp(c) {}</ins>
    <ins>public:</ins>
      <ins>typedef bool result_type;</ins>
      <ins>typedef value_type first_argument_type;</ins>
      <ins>typedef value_type second_argument_type;</ins>
      <ins>bool operator()(const value_type&amp; x, const value_type&amp; y) const {</ins>
        <ins>return comp(x.first, y.first);</ins>
      <ins>}</ins>
    <ins>};</ins>

    <ins><i>// observers:</i></ins>
    <ins>value_compare value_comp() const;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>

<pre><ins>value_compare value_comp() const;</ins></pre>

<li><ins>
<i>Returns:</i> an object of type <tt>value_compare</tt> constructed out of the
comparison object.
</ins></li>

<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class Key, class T, class Compare = less&lt;Key&gt;,</ins>
            <ins>class Allocator = allocator&lt;pair&lt;const Key, T&gt; &gt; &gt;</ins>
  <ins>class multimap {</ins>
  <ins>public:</ins>
     <ins>class value_compare {</ins>
     <ins>friend class multimap;</ins>
     <ins>protected:</ins>
       <ins>Compare comp;</ins>
       <ins>value_compare(Compare c) : comp(c) {}</ins>
     <ins>public:</ins>
       <ins>typedef bool result_type;</ins>
       <ins>typedef value_type first_argument_type;</ins>
       <ins>typedef value_type second_argument_type;</ins>
       <ins>bool operator()(const value_type&amp; x, const value_type&amp; y) const {</ins>
         <ins>return comp(x.first, y.first);</ins>
       <ins>}</ins>
    <ins>};</ins>

    <ins><i>// observers:</i></ins>
    <ins>value_compare value_comp() const;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>
</li>

<pre><ins>value_compare value_comp() const;</ins></pre>

<li><ins>
<i>Returns:</i> an object of type <tt>value_compare</tt> constructed out of the
comparison object.
</ins></li>


<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class Key, class Compare = less&lt;Key&gt;,</ins>
            <ins>class Allocator = allocator&lt;Key&gt; &gt;</ins>
  <ins>class set {</ins>
  <ins>public:</ins>
    <ins><i>// types</i></ins>
    <ins>typedef Compare value_compare;</ins>

    <ins><i>// observers:</i></ins>
    <ins>value_compare value_comp() const;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>

<pre><ins>value_compare value_comp() const;</ins></pre>

<li><ins>
<i>Returns:</i> an object of type <tt>value_compare</tt> constructed out of the
comparison object.
</ins></li>


<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class Key, class Compare = less&lt;Key&gt;,</ins>
            <ins>class Allocator = allocator&lt;Key&gt; &gt;</ins>
  <ins>class multiset {</ins>
  <ins>public:</ins>
    <ins>typedef Compare value_compare;</ins>

    <ins><i>// observers:</i></ins>
    <ins>value_compare value_comp() const;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>

<pre><ins>value_compare value_comp() const;</ins></pre>

<li><ins>
<i>Returns:</i> an object of type <tt>value_compare</tt> constructed out of the
comparison object.
</ins></li>
</ol>

<h4><a name="4.16"><ins>D.y Basic iterator [depr.iterator.basic]</ins></a></h4>
<ol>
<li><ins>
The header <tt>&lt;iterator&gt;</tt> has the following addition:</ins>
<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template&lt;class Category, class T, class Distance = ptrdiff_t,</ins>
    <ins>class Pointer = T*, class Reference = T&amp;&gt;</ins>
  <ins>struct iterator {</ins>
    <ins>typedef T         value_type;</ins>
    <ins>typedef Distance  difference_type;</ins>
    <ins>typedef Pointer   pointer;</ins>
    <ins>typedef Reference reference;</ins>
    <ins>typedef Category  iterator_category;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>
</li>
<li><ins>
The <tt>iterator</tt> template may be used as a base class to provide the type
alias members required for the definition of an iterator type.
</ins></li>
<li><ins>
[ <i>Note:</i> If the new iterator type is a class template, then these
aliases will not be visible from within the iterator class's template
definition, but only to callers of that class <i>- end note</i>]
</ins></li>
</ol>

<h4><a name="4.17"><ins>D.z Algorithms with Partially Formed Ranges [depr.algorithm.partial.range]</ins></a></h4>
<ol>
<li><ins>
The following function template overloads are provided by the &lt;algorithm&gt;
header in addition to those specified in Clause 25:
</ins></li>
<blockquote><pre>
<ins>namespace std {</ins>
<blockquote><ins><i>// non-modifying sequence operations:</i></ins>

<ins>template &lt;class InputIterator1, class InputIterator2&gt;</ins>
  <ins>pair &lt;InputIterator1, InputIterator2&gt;</ins>
    <ins>mismatch(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2);</ins>
<ins>template &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</ins>
  <ins>pair &lt;InputIterator1, InputIterator2&gt;</ins>
    <ins>mismatch(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2, BinaryPredicate pred);</ins>

<ins>template &lt;class InputIterator1, class InputIterator2&gt;</ins>
  <ins>bool equal(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2);</ins>
<ins>template &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</ins>
  <ins>bool equal(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2, BinaryPredicate pred);</ins>

<ins>template &lt;class ForwardIterator1, class ForwardIterator2&gt;</ins>
  <ins>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</ins>
                      <ins>ForwardIterator2 first2);</ins>
<ins>template &lt;class ForwardIterator1, class ForwardIterator2,</ins>
                 <ins>class BinaryPredicate&gt;</ins>
  <ins>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</ins>
                      <ins>ForwardIterator2 first2, BinaryPredicate pred);</ins>
</blockquote><ins>}</ins>
</pre></blockquote>

<li><ins>
For each of the following algorithms, <tt>last2</tt> denotes an invented
iterator object equivalent to <tt>first2 + (last1 - first1)</tt>. [
<i>Note:</i> the behavior may undefined if there is no such reachable iterator
&mdash; <i>end note</i> ]
</ins></li>
<blockquote><pre>
<ins>template &lt;class InputIterator1, class InputIterator2&gt;</ins>
  <ins>pair &lt;InputIterator1, InputIterator2&gt;</ins>
    <ins>mismatch(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>mismatch(first1, first2, last1, last2);</tt>
</ins></li>

<blockquote><pre>
<ins>template &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</ins>
  <ins>pair &lt;InputIterator1, InputIterator2&gt;</ins>
    <ins>mismatch(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2, BinaryPredicate pred);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>mismatch(first1, first2, last1, last2, pred);</tt>
</ins></li>

<blockquote><pre>
<ins>template &lt;class InputIterator1, class InputIterator2&gt;</ins>
  <ins>bool equal(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>equal(first1, first2, last1, last2);</tt>
</ins></li>

<blockquote><pre>
<ins>template &lt;class InputIterator1, class InputIterator2, class BinaryPredicate&gt;</ins>
  <ins>bool equal(InputIterator1 first1, InputIterator1 last1,</ins>
             <ins>InputIterator2 first2, BinaryPredicate pred);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>equal(first1, first2, last1, last2, pred);</tt>
</ins></li>

<blockquote><pre>
<ins>template &lt;class ForwardIterator1, class ForwardIterator2&gt;</ins>
  <ins>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</ins>
                      <ins>ForwardIterator2 first2);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>is_permutation(first1, first2, last1, last2);</tt>
</ins></li>

<blockquote><pre>
<ins>template &lt;class ForwardIterator1, class ForwardIterator2,</ins>
                 <ins>class BinaryPredicate&gt;</ins>
  <ins>bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,</ins>
                      <ins>ForwardIterator2 first2, BinaryPredicate pred);</ins>
</pre></blockquote>
<li><ins>
<i>Effects:</i> equivalent to <tt>is_permutation(first1, first2, last1, last2, pred);</tt>
</ins></li>
</ol>


<h2><a name="5.0">Acknowledements</h2>
<p>
</p>


<h2><a name="6.0">References</h2>
<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3671.html">N3671</a> Making non-modifying sequence operations more robust: Revision 2, Mike Spertus, Attila Pall</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0090r0.htm">P0090R0</a> Removing result_type, etc., Stephan T. Lavavej</li>
</ul>


</body>
</html>
