<html>

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

<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">P0174R2</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2016-06-23</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>
  <li><a href="#rev.1">Revision 1</a></li>
  <li><a href="#rev.2">Revision 2</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 the Redundant Members of <tt>std::allocator</tt></a></li>
  <li><a href="#3.3">Deprecate <tt>is_literal</tt>  Trait</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 the Temporary Buffer APIs</a></li>
  <li><a href="#3.3">Reconsider raw storage iterators</a></li>
  <li><a href="#3.4">Reconsider algorithms taking half an input range</a></li>
  <li><a href="#3.5">Reconsider <tt>value_compare</tt> Predicates</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">20.9.10 Raw storage iterator [storage.iterator]</a></li>
  <li><a href="#4.4">20.9.11 Temporary buffers [temporary.buffer]</a></li>
  <li><a href="#4.5">20.10.2 Header <tt>&lt;type_traits&gt;</tt> synopsis [meta.type.synop]</a></li>
  <ul>
    <li><a href="#4.5.1">20.10.4.3 Type properties [meta.unary.prop]</a></li>
  </ul>
  <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.V">D.v The default allocator [depr.default.allocator]</a></li>
  <li><a href="#4.W">D.w Raw storage iterator [depr.storage.iterator]</a></li>
  <li><a href="#4.X">D.x Temporary buffers [depr.temporary.buffer]</a></li>
  <li><a href="#4.Y">D.y Deprecated Type Traits [depr.meta.type]</a></li>
  <li><a href="#4.Z">D.z Basic iterator [depr.iterator.basic]</a></li>
  </ul>
<li><a href="#5.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>


<h3><a name="rev.1">Revision 1</a></h3>
<p>
Following Jacksonville review.
</p>
<ul>
<li>Do not deprecate algorithms with incomplete ranges</li>
<li>Do not deprecate <tt>value_compare</tt> predicates</li>
<li>Deprecate <tt>is_literal_type</tt> now</li>
<li>Deprecate even more of <tt>std::allocator</tt></li>
<li>Deprecate temporary buffer APIs now</li>
<li>Deprecate <tt>raw_storage_iterator</tt> now</li>
</ul>

<h3><a name="rev.2">Revision 2</a></h3>
<p>
Following Jacksonville review.
</p>
<ul>
<li>Clean up editorial nits from LWG review</li>
<li>Better wording to introduce deprecated class specializations</li>
</ul>


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


<p>
<b>Update from Jacksonville, 2016:</b>
</p>

<p>
<b>Poll:</b> Deprecate <tt>iterator</tt> for C++17??
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>6</td>
  <td>10</td>
  <td>1</td>
  <td>0</td>
  <td>0</td>
</tr>
</table>

<h3><a name="2.2">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>

<p>
<b>Update from Jacksonville, 2016:</b>
</p>

<p>
<b>Poll:</b> Deprecate Redundant <tt>allocator</tt> Parts for C++17??
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>9</td>
  <td>7</td>
  <td>1</td>
  <td>0</td>
  <td>0</td>
</tr>
</table>

<p>
<b>Poll:</b> Deprecate move aggressively (<tt>max_size</tt> and <tt>allocate</tt> hint) for C++17??
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>5</td>
  <td>7</td>
  <td>4</td>
  <td>1</td>
  <td>0</td>
</tr>
</table>


<h3><a name="2.3">Deprecate the <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>
The next step towards removal (after deprecation) would be to write a paper
proposing to remove the term from the core language while deprecating/removing
the type trait.
</p>

<p>
<b>Update from Jacksonville, 2016:</b>
</p>

<p>
<b>Poll:</b> Deprecate <tt>is_literal</tt> for C++17?
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>9</td>
  <td>4</td>
  <td>3</td>
  <td>1</td>
  <td>0</td>
</tr>
</table>


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

<p>
<b>Update from Jacksonville, 2016:</b>
</p>

<p>
<b>Poll:</b> Deprecate the temporary buffer API?
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>5</td>
  <td>10</td>
  <td>2</td>
  <td>1</td>
  <td>0</td>
</tr>
</table>

<h3><a name="3.3">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>

<p>
<b>Update from Jacksonville, 2016:</b>
</p>

<p>
<b>Poll:</b> Deprecate raw storage iterators (at next opportunity)?
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>2</td>
  <td>12</td>
  <td>2</td>
  <td>2</td>
  <td>0</td>
</tr>
</table>


<h3><a name="3.4">Reconsider 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>

<p>
<b>Update from Jacksonville, 2016:</b>
</p>
<p>
<b>Poll:</b> Deprecate the listed algorithms with half-specified ranges?
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>3</td>
  <td>6</td>
  <td>3</td>
  <td>5</td>
  <td>1</td>
</tr>
</table>

<p>
There is no consensus to deprecate at this point, although interest remains
to revisit for a future standard, probably after the Ranges TS has landed.
</p>

<h3><a name="3.5">Reconsider <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>


<p>
<b>Update from Jacksonville, 2016:</b>
</p>
<p>
<b>Poll:</b> Replace value_compare by unspecified type with the same semantics
(for after C++17)?
</p>
<table>
<tr>
  <td><b>SF</b></td>
  <td><b>F</b></td>
  <td><b>N</b></td>
  <td><b>A</b></td>
  <td><b>SA</b></td>
</tr>
<tr>
  <td>5</td>
  <td>10</td>
  <td>2</td>
  <td>0</td>
  <td>0</td>
</tr>
</table>


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

  <del><i>// 20.9.10, raw storage iterator:</i></del>
  <del>template &lt;class OutputIterator, class T&gt; class raw_storage_iterator;</del>

  <del><i>// 20.9.11, temporary buffers:</i></del>
  <del>template &lt;class T&gt;</del>
    <del>pair&lt;T*, ptrdiff_t&gt; get_temporary_buffer(ptrdiff_t n) noexcept;</del>
  <del>template &lt;class T&gt;</del>
    <del>void return_temporary_buffer(T* p);</del>

  <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, allocator&lt;void&gt;::const_pointer hint = 0</del>);
    void deallocate(<del>pointer</del><ins>T*</ins> p, size_t<del>ype</del> n);
    <del>size_type max_size() const noexcept;</del>
    <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_t<del>ype</del> n, <del>allocator<void>::const_pointer hint = 0</del>);</pre>
<li><del>
[ <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>
]
</del></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. <del>The use of <tt>hint</tt> is unspecified, but intended
as an aid to locality if an implementation so desires.</del>
</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><del>size_type max_size() const noexcept;</ins></del></pre>
<li><del>
<i>Returns:</i> The largest value <tt>N</tt> for which the call
<tt>allocate(N,0)</tt> might succeed.
</del></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>


<h3><a name="4.3">20.9.10 Raw storage iterator [storage.iterator]</a></h3>
<ol>
<li><del>
<tt>raw_storage_iterator</tt> is provided to enable algorithms to store their
results into uninitialized memory. The template parameter
<tt>OutputIterator</tt> is required to have its <tt>operator*</tt> return an
object for which <tt>operator&amp;</tt> is defined and returns a pointer to
<tt>T</tt>, and is also required to satisfy the requirements of an output
iterator (24.2.4).
</del></li>
<pre>
  <del>namespace std {</del>
    <del>template &lt;class OutputIterator, class T&gt;</del>
    <del>class raw_storage_iterator {</del>
    <del>public:</del>
      <del>typedef output_iterator_tag iterator_category;</del>
      <del>typedef void value_type;</del>
      <del>typedef void difference_type;</del>
      <del>typedef void pointer;</del>
      <del>typedef void reference;</del>

      <del>explicit raw_storage_iterator(OutputIterator x);</del>

      <del>raw_storage_iterator&amp; operator*();</del>
      <del>raw_storage_iterator&amp; operator=(const T&amp; element);</del>
      <del>raw_storage_iterator&amp; operator=(T&amp;&amp; element);</del>
      <del>raw_storage_iterator&amp; operator++();</del>
      <del>raw_storage_iterator  operator++(int);</del>
      <del>OutputIterator base() const;</del>
    <del>};</del>
  <del>}</del>
</pre>

<pre>
<del>explicit raw_storage_iterator(OutputIterator x);</del>
</pre>
<li><del>
<i>Effects:</i> Initializes the iterator to point to the same value to which
<tt>x</tt> points.
</del></li>

<pre>
<del>raw_storage_iterator&amp; operator*();</del>
</pre>
<li><del>
<i>Returns:</i> <tt>*this</tt>
</del></li>

<pre>
<del>raw_storage_iterator&amp; operator=(const T&amp; element);</del>
</pre>
<li><del>
<i>Requires:</i> <tt>T</tt> shall be <tt>CopyConstructible</tt>.
</del></li>
<li><del>
<i>Effects:</i> Constructs a value from <tt>element</tt> at the location to
which the iterator points.
</del></li>
<li><del>
<i>Returns:</i> A reference to the iterator.
</del></li>

<pre>
<del>raw_storage_iterator&amp; operator=(T&amp;&amp; element);</del>
</pre>
<li><del>
<i>Requires:</i> <tt>T</tt> shall be <tt>MoveConstructible</tt>.
</del></li>
<li><del>
<i>Effects:</i> Constructs a value from <tt>std::move(element)</tt> at the
location to which the iterator points.
</del></li>
<li><del>
<i>Returns:</i> A reference to the iterator.
</del></li>

<pre>
<del>raw_storage_iterator&amp; operator++();</del>
</pre>
<li><del>
<i>Effects:</i> Pre-increment: advances the iterator and returns a reference to
the updated iterator.
</del></li>

<pre>
<del>raw_storage_iterator operator++(int);</del>
</pre>
<li><del>
<i>Effects:</i> Post-increment: advances the iterator and returns the old value
of the iterator.
</del></li>

<pre>
<del>OutputIterator base() const;</del>
</pre>
<li><del>
<i>Returns:</i> An iterator of type <tt>OutputIterator</tt> that points to the
same value as <tt>*this</tt> points to.
</del></li>
</ol>

<h3><a name="4.4"><del>20.9.11 Temporary buffers [temporary.buffer]</del></a></h3>
<pre>
<del>template &lt;class T&gt;</del>
  <del>pair&lt;T*, ptrdiff_t&gt; get_temporary_buffer(ptrdiff_t n) noexcept;</del>
</pre>
<ol>
<li><del>
<i>Effects:</i> Obtains a pointer to uninitialized, contiguous storage for
<i>N</i> adjacent objects of type <tt>T</tt>, for some non-negative number
<i>N</i>. It is implementation-defined whether over-aligned types are supported
(3.11).
</del></li>
<li><del>
<i>Remarks:</i> Calling <tt>get_temporary_buffer</tt> with a positive number
<tt>n</tt> is a non-binding request to return storage for <tt>n</tt> objects of
type <tt>T</tt>. In this case, an implementation is permitted to return instead
storage for a non-negative number <i>N</i> of such objects, where
<i>N</i><tt>!= n</tt> (including <i>N</i><tt> == 0</tt>). [ <i>Note:</i> The
request is non-binding to allow latitude for implementation-specific
optimizations of its memory management.  - <i>end note</i> ]
</del></li>
<li><del>
<i>Returns:</i> If <tt>n &lt;= 0</tt> or if no storage could be obtained,
returns a pair <tt>P</tt> such that <tt>P.first</tt> is a null pointer value
and <tt>P.second == 0</tt>; otherwise returns a pair <tt>P</tt> such that
<tt>P.first</tt> refers to the address of the uninitialized storage and
<tt>P.second</tt> refers to its capacity <i>N</i> (in the units of
<tt>sizeof(T)</tt>).
</del></li>
</ol>

<pre>
<del>template &lt;class T&gt; void return_temporary_buffer(T* p);</del>
</pre>
<ol>
<li><del>
<i>Effects:</i> Deallocates the storage referenced by <tt>p</tt>.
</del></li>
<li><del>
<i>Requires:</i> <tt>p</tt> shall be a pointer value returned by an earlier
call to <tt>get_temporary_buffer</tt> that has not been invalidated by an
intervening call to <tt>return_temporary_buffer(T*)</tt>.
</del></li>
<li><del>
<i>Throws:</i> Nothing.
</del></li>
</ol>


<h3><a name="4.5">20.10.2 Header <tt>&lt;type_traits&gt;</tt> synopsis [meta.type.synop]</a></h3>
<blockquote><pre>
namespace std {
  <i>// Start of header elided...</i>

  <i>// 20.10.4.3, type properties:</i>
  template &lt;class T&gt; struct is_const;
  template &lt;class T&gt; struct is_volatile;
  template &lt;class T&gt; struct is_trivial;
  template &lt;class T&gt; struct is_trivially_copyable;
  template &lt;class T&gt; struct is_standard_layout;
  template &lt;class T&gt; struct is_pod;
  <del>template &lt;class T&gt; struct is_literal_type;</del>
  template &lt;class T&gt; struct is_empty;
  template &lt;class T&gt; struct is_polymorphic;
  template &lt;class T&gt; struct is_abstract;
  template &lt;class T&gt; struct is_final;

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

<h3><a name="4.5.1">20.10.4.3 Type properties [meta.unary.prop]</a></h3>
<p>
Table 49 - Type property predicates
</p>
<table>
<tr>
  <td><b>Template</b></td>
  <td><b>Condition</b></td>
  <td><b>Preconditions</b></td>
</tr>
<tr>
  <td>
<pre><del>template &lt;class T&gt;
struct is_literal_type;</del></pre>
  </td>
  <td><del><tt>T</tt> is a literal type (3.9)</del></td>
  <td><del>
    <tt>remove_all_extents_t&lt;T&gt;</tt> shall be a complete
    type or (possibly cv-qualified) <tt>void</tt>.
  </del></td>
</tr>
</table>

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

</blockquote>


<p>
Insert new clauses into Annex D:
</p>

<blockquote>
<h3><a name="4.v"><ins>D.v The default allocator [depr.default.allocator]</ins></a></h3>
<ol>
<li><ins>The following members and explicit class template specialization 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>T* address(reference x) const noexcept;</ins>
    <ins>const T* address(const_reference x) const noexcept;</ins>

    <ins>T* allocate(size_t, const void* hint);</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>size_t max_size() const noexcept;</ins>
  <ins>};</ins>
<ins>}</ins>
</pre></blockquote>

<pre><ins>T* 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 T* 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>T* allocate(size_t, const void* hint);</ins></pre>
<li><ins>
<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).
</ins></li>
<li><ins>
<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.
</ins></li>
<li><ins>
<i>Throws:</i> <tt>bad_alloc</tt> if the storage cannot be obtained.
</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>

<pre><ins>size_type max_size() const noexcept;</ins></pre>
<li><ins>
<i>Returns:</i> The largest value <tt>N</tt> for which the call
<tt>allocate(N)</tt> might succeed.
</ins></li>
</ol>


<h3><a name="4.W"><ins>D.w Raw storage iterator [depr.storage.iterator]</ins></a></h3>
<ol>
<p><ins>
The header <tt>&lt;memory&gt;</tt> has the following addition:</ins>
</ins></p>

<pre>
  <ins>namespace std {</ins>
    <ins>template &lt;class OutputIterator, class T&gt;</ins>
    <ins>class raw_storage_iterator {</ins>
    <ins>public:</ins>
      <ins>typedef output_iterator_tag iterator_category;</ins>
      <ins>typedef void value_type;</ins>
      <ins>typedef void difference_type;</ins>
      <ins>typedef void pointer;</ins>
      <ins>typedef void reference;</ins>

      <ins>explicit raw_storage_iterator(OutputIterator x);</ins>

      <ins>raw_storage_iterator&amp; operator*();</ins>
      <ins>raw_storage_iterator&amp; operator=(const T&amp; element);</ins>
      <ins>raw_storage_iterator&amp; operator=(T&amp;&amp; element);</ins>
      <ins>raw_storage_iterator&amp; operator++();</ins>
      <ins>raw_storage_iterator  operator++(int);</ins>
      <ins>OutputIterator base() const;</ins>
    <ins>};</ins>
  <ins>}</ins>
</pre>

<li><ins>
<tt>raw_storage_iterator</tt> is provided to enable algorithms to store their
results into uninitialized memory. The template parameter
<tt>OutputIterator</tt> is required to have its <tt>operator*</tt> return an
object for which <tt>operator&amp;</tt> is defined and returns a pointer to
<tt>T</tt>, and is also required to satisfy the requirements of an output
iterator (24.2.4).
</ins></li>

<pre>
<ins>explicit raw_storage_iterator(OutputIterator x);</ins>
</pre>
<li><ins>
<i>Effects:</i> Initializes the iterator to point to the same value to which
<tt>x</tt> points.
</ins></li>

<pre>
<ins>raw_storage_iterator&amp; operator*();</ins>
</pre>
<li><ins>
<i>Returns:</i> <tt>*this</tt>
</ins></li>

<pre>
<ins>raw_storage_iterator&amp; operator=(const T&amp; element);</ins>
</pre>
<li><ins>
<i>Requires:</i> <tt>T</tt> shall be <tt>CopyConstructible</tt>.
</ins></li>
<li><ins>
<i>Effects:</i> Constructs a value from <tt>element</tt> at the location to
which the iterator points.
</ins></li>
<li><ins>
<i>Returns:</i> A reference to the iterator.
</ins></li>

<pre>
<ins>raw_storage_iterator&amp; operator=(T&amp;&amp; element);</ins>
</pre>
<li><ins>
<i>Requires:</i> <tt>T</tt> shall be <tt>MoveConstructible</tt>.
</ins></li>
<li><ins>
<i>Effects:</i> Constructs a value from <tt>std::move(element)</tt> at the
location to which the iterator points.
</ins></li>
<li><ins>
<i>Returns:</i> A reference to the iterator.
</ins></li>

<pre>
<ins>raw_storage_iterator&amp; operator++();</ins>
</pre>
<li><ins>
<i>Effects:</i> Pre-increment: advances the iterator and returns a reference to
the updated iterator.
</ins></li>

<pre>
<ins>raw_storage_iterator operator++(int);</ins>
</pre>
<li><ins>
<i>Effects:</i> Post-increment: advances the iterator and returns the old value
of the iterator.
</ins></li>

<pre>
<ins>OutputIterator base() const;</ins>
</pre>
<li><ins>
<i>Returns:</i> An iterator of type <tt>OutputIterator</tt> that points to the
same value as <tt>*this</tt> points to.
</ins></li>
</ol>


<h3><a name="4.X"><ins>D.x Temporary buffers [depr.temporary.buffer]</ins></a></h3>
<ol>
<li><ins>
The header <tt>&lt;memory&gt;</tt> has the following additional functions:</ins>
</ins></li>
<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class T&gt;</ins>
    <ins>pair&lt;T*, ptrdiff_t&gt; get_temporary_buffer(ptrdiff_t n) noexcept;</ins>
  <ins>template &lt;class T&gt;</ins>
    <ins>void return_temporary_buffer(T* p);</ins>
<ins>}</ins>
</pre></blockquote>

<pre>
<ins>template &lt;class T&gt;</ins>
  <ins>pair&lt;T*, ptrdiff_t&gt; get_temporary_buffer(ptrdiff_t n) noexcept;</ins>
</pre>
<li><ins>
<i>Effects:</i> Obtains a pointer to uninitialized, contiguous storage for
<i>N</i> adjacent objects of type <tt>T</tt>, for some non-negative number
<i>N</i>. It is implementation-defined whether over-aligned types are supported
(3.11).
</ins></li>
<li><ins>
<i>Remarks:</i> Calling <tt>get_temporary_buffer</tt> with a positive number
<tt>n</tt> is a non-binding request to return storage for <tt>n</tt> objects of
type <tt>T</tt>. In this case, an implementation is permitted to return instead
storage for a non-negative number <i>N</i> of such objects, where
<i>N</i><tt>!= n</tt> (including <i>N</i><tt> == 0</tt>). [ <i>Note:</i> The
request is non-binding to allow latitude for implementation-specific
optimizations of its memory management.  - <i>end note</i> ]
</ins></li>
<li><ins>
<i>Returns:</i> If <tt>n &lt;= 0</tt> or if no storage could be obtained,
returns a pair <tt>P</tt> such that <tt>P.first</tt> is a null pointer value
and <tt>P.second == 0</tt>; otherwise returns a pair <tt>P</tt> such that
<tt>P.first</tt> refers to the address of the uninitialized storage and
<tt>P.second</tt> refers to its capacity <i>N</i> (in the units of
<tt>sizeof(T)</tt>).
</ins></li>
</ol>

<pre>
<ins>template &lt;class T&gt; void return_temporary_buffer(T* p);</ins>
</pre>
<ol>
<li><ins>
<i>Effects:</i> Deallocates the storage referenced by <tt>p</tt>.
</ins></li>
<li><ins>
<i>Requires:</i> <tt>p</tt> shall be a pointer value returned by an earlier
call to <tt>get_temporary_buffer</tt> that has not been invalidated by an
intervening call to <tt>return_temporary_buffer(T*)</tt>.
</ins></li>
<li><ins>
<i>Throws:</i> Nothing.
</ins></li>
</ol>


<h3><a name="4.Y"><ins>D.y Deprecated Type Traits [depr.meta.type]</ins></a></h3>
<ol>
<li><ins>
The header <tt>&lt;type_traits&gt;</tt> has the following addition:</ins>
</ins></li>

<blockquote><pre>
<ins>namespace std {</ins>
  <ins>template &lt;class T&gt; struct is_literal_type;</ins>
<ins>}</ins>
</pre></blockquote>

<li><ins>
<i>Requires:</i> <tt>remove_all_extents_t&lt;T&gt;</tt> shall be a complete
type or (possibly cv-qualified) <tt>void</tt>.
</ins></li>

<li><ins>
<i>Effects:</i> <tt>is_literal_type</tt> has a base-characteristic of
<tt>true_type</tt> if <tt>T</tt> is a literal type (3.9), and a
base-characteristic of <tt>false_type</tt> otherwise.
</ins></li>
</ol>


<h3><a name="4.Z"><ins>D.z Basic iterator [depr.iterator.basic]</ins></a></h3>
<ol>
<li><ins>
The header <tt>&lt;iterator&gt;</tt> has the following addition:</ins>
</ins></li>
<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><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>


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