<html>
<head>
<title>Rvalue Reference Recommendations for Chapter 20</title>
<style>
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:#FFFFA0}
del {background-color:#FFFFA0}
</style>
</head>

<body>

<address align=right>
Document number: N1856=05-0116<br>
<br>
<a href="mailto:hinnant@twcny.rr.com">Howard E. Hinnant</a><br>
2005-08-26
</address>
<hr>

<h1 align=center>Rvalue Reference Recommendations for Chapter 20</h1>

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li>
<a href="#20.1 - Requirements">20.1 - Requirements</a>
	<ul>
	<li><a href="#20.1.3 - Move construction">20.1.3 - Move construction</a></li>
	<li><a href="#20.1.4 - Copy construction">20.1.4 - Copy construction</a></li>
	<li><a href="#20.1.5 - Move assignment">20.1.5 - Move assignment</a></li>
	<li><a href="#20.1.6 - Copy assignment">20.1.6 - Copy assignment</a></li>
	<li><a href="#20.1.9 - Destruction requirements">20.1.9 - Destruction requirements</a></li>
	<li><a href="#20.1.10 - Allocator requirements">20.1.10 - Allocator requirements</a></li>
	</ul>
</li>
<li>
<a href="#20.2 - Utility components">20.2 - Utility components</a>
	<ul>
	<li>
	<a href="#20.2.2 - move/forward helpers">20.2.2 - move/forward helpers</a>
	</li>
	<li>
	<a href="#20.2.3 - Pairs">20.2.3 - Pairs</a>
	</li>
	</ul>
</li>
<li>
<a href="#20.4 - Memory">20.4 - Memory</a>
	<ul>
	<li>
	<a href="#20.4.1 - The default allocator">20.4.1 - The default allocator</a>
	</li>
	<li>
	<a href="#20.4.5 - Class template auto_ptr">20.4.5 - Class template
auto_ptr</a>
		<ul>
		<li>
		<a href="#Addition - Class template unqiue_ptr">Addition - Class template
unqiue_ptr</a>
		</li>
		</ul> 	</li> 	</ul>
</li>
<li><a href="#Acknowledgments">Acknowledgments</a></li>
</ul>

<h2>Related papers</h2>

<p>
<a href="n1857.html">Rvalue Reference Recommendations for Chapter 21</a><br>
<a href="n1858.html">Rvalue Reference Recommendations for Chapter 23</a><br>
<a href="n1859.html">Rvalue Reference Recommendations for Chapter 24</a><br>
<a href="n1860.html">Rvalue Reference Recommendations for Chapter 25</a><br>
<a href="n1861.html">Rvalue Reference Recommendations for Chapter 26</a><br>
<a href="n1862.html">Rvalue Reference Recommendations for Chapter 27</a>
</p>

<h2><a name="Introduction"></a>Introduction</h2>

<p>
This paper recommends proposed wording with respect to the
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">rvalue
reference</a> for the
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1804.pdf">C++0X
working draft</a>.
This paper restricts its scope to Chapter 20 "General utilities library" for the
purpose of breaking the library work associated with the rvalue reference up
into manageable chunks. This paper largely follows the lead of
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1771.html">N1771:
Impact of the rvalue reference on the Standard Library</a>, but adds more detail
as appropriate.
</p>

<p>
With the exception of this introduction, all non-proposed wording will have a
background color and formatting that
</p>
<blockquote class="note">
looks like this, so that motivation and description is more easily distinguished
from proposed wording.
</blockquote>
<p>
In the proposed wording below, text to be inserted is formatted like
<ins>this</ins>, while wording to be deleted is formatted like <del>this</del>.
</p>

<p>
The proposed wording in this paper:
</p>

<ul>
<li>Introduces new concepts: <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt>.</li>
<li> <tt>CopyConstructible</tt> is simplified, and <tt>Assignable</tt> is renamed to <tt>CopyAssignable</tt>.</li>
<li>The <tt>move</tt> and <tt>forward</tt> utility functions are introduced.</li>
<li><tt>pair</tt> is made <i>move-aware</i>.</li>
<li>The default allocator and the allocator requirements are updated with a new <tt>construct</tt>
overload to aid moving rvalues into associative containers.</li>
<li><tt>auto_ptr</tt> is deprecated, and <tt>unique_ptr</tt> is proposed
in its place.
</li>
</ul>

<h2><a name="20.1 - Requirements"></a>20.1 - Requirements</h2>

<blockquote class="note">

<p>
The following proposed wordings accomplish several things: </p>

<ul>
<li>
The concepts <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt> are
introduced.
</li>
<li>
The concept <tt>CopyConstructible</tt> is cleaned up, jettisoning the unrelated
concepts of <tt>Addressable</tt> and <tt>Destructible</tt>.  The
<tt>Destructible</tt> requirement is added back in separately.  The
<tt>Addressable</tt> requirement has not been added back in, but easily could
be.
</li>
<li>
The <tt>Assignable</tt> requirement has been renamed to <tt>CopyAssignable</tt>
to distinguish it from <tt>MoveAssignable</tt> and moved here from section 23.1.
</li> </ul>

<p>
The <tt>Swappable</tt> concept is not mentioned herein only because it is
already part of the working draft.  The rvalue reference work depends upon, and
assumes that the <tt>Swappable</tt> concept will remain in the working draft
through standardization. </p>

<p>
The motivation for separating out the different concepts from the old definition
of <tt>CopyConstructible</tt> is to allow containers and algorithms to work with
<i>movable</i> but <i>non-copyable</i> types.  A clean separation of concepts is
helpful in this regard. </p>

<p>
The <tt>Addressable</tt> concept is not strictly needed for C++0X, even though
we currently require it for a container's <tt>value_type</tt>.  Containers
needing the actual address of a <tt>value_type</tt> can use something along the
lines of
<a
href="http://www.boost.org/libs/utility/utility.htm#addressof">boost::addressof</a>
instead of the <tt>value_type</tt>'s <tt>operator&amp;()</tt>. This paper offers
no recommendation on whether to include or exclude an <tt>Addressable</tt>
concept in C++0X. </p>

</blockquote>

<h3><a name="20.1.3 - Move construction"></a>20.1.3 - Move construction</h3>

<p>
<ins>-1- In the following Table 30, <tt>T</tt> is a type to be supplied by a C++
program instantiating a template, <tt>t</tt> is an identifier, and <tt>rv</tt>
is a non-const rvalue of type <tt>T</tt>. </ins>
</p>

<p>Insert the following table:</p>
<p><center>
<table border="1">
<caption>Table 30: <tt>MoveConstructible</tt> requirements</caption>
<tr><th>expression</th> <th>post-condition</th></tr>
<tr><td><tt>T t = rv</tt></td> <td><tt>t</tt> is equivalent to the value of <tt>rv</tt> before the construction</td></tr>
</table>
</center></p>

<p>
<ins>[<i>Note:</i> There is no requirement on the value of <tt>rv</tt> after the
construction. <i>-- end note</i>]</ins>
</p>

<h3><a name="20.1.4 - Copy construction"></a>20.1.<del>3</del> <ins>4</ins> - Copy construction</h3>

<p>
-1- In the following Table <del>30</del> <ins>31</ins>, <tt>T</tt> is a type to
be supplied by a C++ program instantiating a template, <tt>t</tt> is <ins>an
identifier</ins> <del>a value of type <tt>T</tt></del>, and <tt>u</tt> is a
value of type <ins>(possibly <tt>const</tt>)</ins> <tt><del>const</del> T</tt>.
</p>

<p>Delete the following table:</p>
<p><center>
<table border="1">
<caption>Table 30: <tt>CopyConstructible</tt> requirements</caption>
<tr><th>expression</th> <th>return type</th> <th>requirement</th></tr>
<tr><td><tt>T(t)</tt></td> <td>&nbsp;</td> <td><tt>t</tt> is equivalent to <tt>T(t)</tt></td></tr>
<tr><td><tt>T(u)</tt></td> <td>&nbsp;</td> <td><tt>u</tt> is equivalent to <tt>T(u)</tt></td></tr>
<tr><td><tt>t.~T()</tt></td> <td>&nbsp;</td> <td>&nbsp;</td></tr>
<tr><td><tt>&amp;t()</tt></td> <td><tt>T*</tt></td> <td>denotes the address of <tt>t</tt></td></tr>
<tr><td><tt>&amp;u()</tt></td> <td><tt>const T*</tt></td> <td>denotes the address of <tt>u</tt></td></tr>
</table>
</center></p>

<p>Insert the following table:</p>

<p><center>
<table border="1">
<caption>Table 31: <tt>CopyConstructible</tt> requirements</caption>
<tr><th>expression</th> <th>post-condition</th></tr>
<tr><td><tt>T t = u</tt></td> <td>The value of <tt>u</tt> is unchanged and is equivalent to
<tt>t</tt></td></tr>
</table>
</center></p>

<p>
<ins>[<i>Note:</i> A type that satisfies the <tt>CopyConstructible</tt>
requirements also satisfies the <tt>MoveConstructible</tt> requirements. <i>--
end note</i>]</ins>
</p>

<h3><a name="20.1.5 - Move assignment"></a>20.1.5 - Move assignment</h3>

<p>
<ins>-1- In the following Table 32, <tt>T</tt> is a type to be supplied by a C++
program instantiating a template, <tt>t</tt> is a value of type <tt>T</tt>, and
<tt>rv</tt> is a non-const rvalue of type <tt>T</tt>. </ins>
</p>

<p>Insert the following table:</p>
<p><center>
<table border="1">
<caption>Table 32: <tt>MoveAssignable</tt> requirements</caption>
<tr><th>expression</th> <th>return type</th> <th>return value</th> <th>post-condition</th></tr>
<tr><td><tt>t = rv</tt></td> <td><tt>T&</tt></td> <td><tt>t</tt></td> <td><tt>t</tt>
is equivalent to the value of <tt>rv</tt> before the assignment</td></tr>
</table>
</center></p>

<p>
<ins>[<i>Note:</i> There is no requirement on the value of <tt>rv</tt> after the
assignment. <i>-- end note</i>]</ins>
</p>

<h3><a name="20.1.6 - Copy assignment"></a>20.1.6 - Copy assignment</h3>

<p>
<ins>-1- In the following Table 33, <tt>T</tt> is a type to be supplied by a C++
program instantiating a template, <tt>t</tt> is a value of type <tt>T</tt>, and
<tt>rv</tt> is a non-const rvalue of type <tt>T</tt>. </ins>
</p>

<p>Insert the following table:</p>
<p><center>
<table border="1">
<caption>Table 33: <tt>CopyAssignable</tt> requirements</caption>
<tr><th>expression</th> <th>return type</th> <th>return value</th> <th>post-condition</th></tr>
<tr><td><tt>t = u</tt></td> <td><tt>T&</tt></td> <td><tt>t</tt></td> <td><tt>t</tt>
is equivalent to <tt>u</tt>, the value of <tt>u</tt> is unchanged</td></tr>
</table>
</center></p>

<p>
<ins>[<i>Note:</i> A type that satisfies the <tt>CopyAssignable</tt>
requirements also satisfies the <tt>MoveAssignable</tt> requirements. <i>-- end
note</i>]</ins>
</p>

<p>
Delete the existing definition of <tt>Assignable</tt> in
<a href="rv_Chap23.html#23.1%20-%20Container%20requirements">23.1, paragraph
4</a>.
</p>

<h3><a name="20.1.9 - Destruction requirements"></a>20.1.9 - Destruction requirements</h3>

<p>
<ins>-1- In the following Table 35, <tt>T</tt> is a type to be supplied by a C++
program instantiating a template, and <tt>u</tt> is a value of type (possibly
<tt>const</tt>) <tt>T</tt>. </ins>
</p>

<p>Insert the following table:</p>

<p><center>
<table border="1">
<caption>Table 35: <tt>Destructible</tt> requirements</caption>
<tr><th>expression</th> <th>post-condition</th></tr>
<tr><td><tt>u.~T()</tt></td> <td>All resources owned by <tt>u</tt> are reclaimed, no
exception is propagated</td></tr>
</table>
</center></p>

<h3><a name="20.1.10 - Allocator requirements"></a>20.1.<del>6</del> <ins>10</ins> - Allocator requirements</h3>

<p>
Append the following two rows to the Table in paragraph 2: Descriptive variable
definitions:
</p>

<p><center>
<table border="1">
<tr><td><tt>V</tt></td> <td>A type convertible to <tt>T</tt></td></tr>
<tr><td><tt>v</tt></td> <td>A value of type <tt>V</tt></td></tr>
</table>
</center></p>

<p>
Append the following row to the Table in paragraph 2: Allocator requirements:
</p>

<p><center>
<table border="1">
<tr><td><tt>a.construct(p,v)</tt></td> <td>(not used)</td> <td>Effect: <tt>::new((void*)p) T(std::forward&lt;V&gt;(v))</tt></td></tr>
</table>
</center></p>

<blockquote class="note">
<p>
The new <tt>construct</tt> overload is typically implemented as a member
template function.  It obsoletes the current non-member template
<tt>construct</tt> member, but the current <tt>construct</tt> member is retained
for binary backwards compatibility. The new overload allows containers to move
construct rvalues from single element insert functions.  It also allows
convertible types <tt>V</tt> to be used to construct types <tt>T</tt>.  This is
necessary (for example) in <tt>map</tt> which must move construct a
<tt>pair&lt;const key, value&gt;</tt> from an rvalue <tt>pair&lt;key,
value&gt;</tt>, because it is not possible to move from a <tt>pair&lt;const key,
value&gt;</tt>. </p>

<p>
Allocators that are not move-aware, and don't meet this requirement will
continue to work in move-aware containers of types meeting the
<tt>CopyConstructible</tt> requirement.  But they will fail at compile time for
move-aware containers of types only meeting the <tt>MoveConstructible</tt>
requirement.  That is, if you want to put moveable but non-copyable types into a
move-aware container, the container's allocator must have this
<tt>construct</tt> overload.  Therefore, this change is 100% backwards
compatible, but required for the proposed new functionality in C++0X. </p>
</blockquote>

<h2><a name="20.2 - Utility components"></a>20.2 - Utility components</h2>

<blockquote class="note">
<p>
In section 20.2, the proposed wording accomplishes two tasks: </p>

<ol>
<li>Introduce the <tt>move</tt> and <tt>forward</tt> helper functions.</li>
<li>Make <tt>pair</tt> <i>move-aware</i>.</li>
</ol>

<p>
The <tt>move</tt> and <tt>forward</tt> helper functions provide a clean and
descriptive syntax to clients for invoking move semantics for lvalues, and for
implementing
<a
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm#s7"><i>perfect
forwarding</i></a> in generic code.
</p>

<p>
The second item allows expensive-to-copy-but-cheaply-movable types to be cheaply
moved into a <tt>pair</tt>.  It also allows pair to contain non-copyable but
movable types.  In either case the resulting pair itself also becomes cheaply
movable (assuming its contained items are cheaply movable).  Both namespace
scope and member swap are added to complete <tt>pair's</tt> efficient, generic
interface. </p>
</blockquote>

<p>
-1- This subclause contains some basic function and class templates that are
used throughout the rest of the library.
</p>

<p>
<b>Header</b> <tt>&lt;utility&gt;</tt> <b>synopsis</b>
</p>

<blockquote><pre>
namespace std {
  // 20.2.1, <i>operators:</i>
  namespace rel_ops {
    template &lt;class T&gt; bool operator !=(const T&, const T&);
    template &lt;class T&gt; bool operator &gt; (const T&, const T&);
    template &lt;class T&gt; bool operator &lt;=(const T&, const T&);
    template &lt;class T&gt; bool operator &gt;=(const T&, const T&);
  }

<ins>
  // 20.2.2, <i>forward / move:</i>
  template &lt;class T&gt; struct identity {typedef T type;};
  template &lt;class T&gt; T&amp;&amp; forward(typename identity&lt;T&gt;::type&amp;&amp;);
  template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp;);
</ins>
  // 20.2.<del>2</del> <ins>3</ins>, <i>pairs:</i>
  template &lt;class T1, class T2&gt; struct pair;
  template &lt;class T1, class T2&gt;
    bool operator ==(const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    bool operator &lt; (const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    bool operator !=(const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    bool operator &gt; (const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    bool operator &gt;=(const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    bool operator &lt;=(const pair&lt;T1,T2&gt;&amp;, const pair&lt;T1,T2&gt;&amp;);
<ins>  template &lt;class T1, class T2&gt;
    void swap(pair&lt;T1,T2&gt;&amp;, pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    void swap(pair&lt;T1,T2&gt;&amp;&amp;, pair&lt;T1,T2&gt;&amp;);
  template &lt;class T1, class T2&gt;
    void swap(pair&lt;T1,T2&gt;&amp;, pair&lt;T1,T2&gt;&amp;&amp;);</ins>
  template &lt;class T1, class T2&gt; pair&lt;T1,T2&gt; make_pair(T1, T2);
}
</pre></blockquote>

<h3><a name="20.2.2 - move/forward helpers"></a><ins>20.2.2 - move/forward helpers</ins></h3>

<p><ins>
-1- The library provides templated helper functions to simplify applying move
semantics to an lvalue, and to simplify the implementation of forwarding
functions.
</ins></p>

<blockquote><pre><ins>
template &lt;class T&gt; struct identity {typedef T type;};
</ins></pre></blockquote>

<p><ins>
-2- The use of <tt>identity</tt> in <tt>forward</tt> forces client code to
explicitly specify the template parameter.  This is necessary in order to get
the correct forwarding semantics.
</ins></p>

<blockquote><pre><ins>
template &lt;class T&gt; T&amp;&amp; forward(typename identity&lt;T&gt;::type&amp;&amp; t);
</ins></pre></blockquote>

<p><ins>
-3- <i>Returns:</i> <tt>t</tt>.
</ins></p>

<p><ins>
-4- <i>Note:</i> If <tt>T</tt> is an lvalue-reference type, <tt>t</tt> will be
returned from <tt>forward</tt> as an lvalue.  Otherwise <tt>t</tt> it will be
returned as an rvalue.
</ins></p>

<p><ins>
-5- <i>Example:</i>
</ins></p>

<blockquote><pre><ins>
template &lt;class T, class A1, class A2&gt;
shared_ptr&lt;T&gt;
factory(A1&amp;&amp; a1, A2&amp;&amp; a2)
{
    return shared_ptr&lt;T&gt;(new T(forward&lt;A1&gt;(a1),
                               forward&lt;A2&gt;(a2)));
}

struct A
{
    A(int&amp;, const double&amp;);
};

int main()
{
    shared_ptr&lt;A&gt; sp1 = factory&lt;A&gt;(2, 1.414);  // does not compile,
                                               // 2 will not bind to int&amp;
    int i = 2;
    shared_ptr&lt;A&gt; sp2 = factory&lt;A&gt;(i, 1.414);  // ok
}
</ins></pre></blockquote>

<p><ins>
<i>-- end example</i>
</ins></p>

<p><ins>
-6- In the above example, <tt>A1</tt> is deduced as <tt>int</tt> in the first
call to <tt>factory</tt>, and thus 2 is forwarded to <tt>A</tt>'s constructor as
an <tt>int&amp;&amp;</tt> (an rvalue).  However in the second call to
<tt>factory</tt> <tt>A1</tt> is deduced as <tt>int&amp;</tt>, and therefore
<tt>i</tt> is forwarded to <tt>A</tt>'s constructor as an <tt>int&amp;</tt> (an
lvalue). In both calls to <tt>factory</tt>, <tt>A2</tt> is deduced as
<tt>double</tt> with the result that <tt>1.414</tt> is passed to <tt>A</tt>'s
constructor as a <tt>double&amp;&amp;</tt> (an rvalue).
</ins></p>

<blockquote><pre><ins>
template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp; t);
</ins></pre></blockquote>

<p><ins>
-7- <i>Returns:</i> <tt>t</tt>.
</ins></p>

<p><ins>
-8- <i>Note:</i> <tt>t</tt> is returned as an rvalue.
</ins></p>

<p><ins>
-9- <i>Example:</i>
</ins></p>

<blockquote><pre><ins>
template &lt;class T, class A1&gt;
shared_ptr&lt;T&gt;
factory(A1&amp;&amp; a1)
{
    return shared_ptr&lt;T&gt;(new T(forward&lt;A1&gt;(a1)));
}

struct A
{
    A();
    A(const A&amp;);  // lvalues are copied from
    A(A&amp;&amp;);       // rvalues are moved from
};

int main()
{
    A a;
    shared_ptr&lt;A&gt; sp1 = factory&lt;A&gt;(a);        // "a" binds to A(const A&amp;)
    shared_ptr&lt;A&gt; sp2 = factory&lt;A&gt;(move(a));  // "a" binds to A(A&amp;&amp;)
}
</ins></pre></blockquote>

<p><ins>
<i>-- end example</i>
</ins></p>

<p><ins>
-10- In the above example the first call to <tt>factory</tt> deduces <tt>A1</tt>
as <tt>A&amp;</tt> and therefore <tt>a</tt> is forwarded as a non-const lvalue
which binds to the <tt>A(const A&)</tt> constructor, copying from <tt>a</tt>.
However in the second call of <tt>factory</tt>, due to the call of
<tt>move(a)</tt>, <tt>A1</tt> in <tt>factory</tt> is deduced as simply
<tt>A</tt>. Therefore <tt>forward</tt> forwards an rvalue <tt>A</tt> to the
constructor which subsequently binds to <tt>A(A&&)</tt> resulting in <tt>a</tt>
being moved from.
</ins></p>

<h3><a name="20.2.3 - Pairs"></a>20.2.<del>2</del> <ins>3</ins> - Pairs</h3>

<p>
-1- The library provides a template for heterogeneous pairs of values. The
library also provides a matching function template to simplify their
construction.
</p>

<blockquote><pre>
template &lt;class T1, class T2&gt;
struct pair {
  typedef T1 first_type;
  typedef T2 second_type;

  T1 first;
  T2 second;
  pair();
  pair(const T1&amp; <i>x</i>, const T2&amp; <i>y</i>);
  <ins>template&lt;class <i>U</i>, class <i>V</i>&gt; pair(<i>U</i>&amp;&amp; <i>x</i>, <i>V</i>&amp;&amp; <i>y</i>);</ins>
  <ins>pair(pair&amp;&amp; <i>p</i>);</ins>
  template&lt;class <i>U</i>, class <i>V</i>&gt; pair(const pair&lt;<i>U</i>, <i>V</i>&gt;&amp; <i>p</i>);
  <ins>template&lt;class <i>U</i>, class <i>V</i>&gt; pair(pair&lt;<i>U</i>, <i>V</i>&gt;&amp;&amp; <i>p</i>);</ins>

  <ins>pair&amp; operator=(pair&amp;&amp; <i>p</i>);</ins>
  <ins>template&lt;class <i>U</i>, class <i>V</i>&gt; pair&amp; operator=(pair&lt;<i>U</i>, <i>V</i>&gt;&amp;&amp; <i>p</i>);</ins>

  <ins>void swap(pair&amp;&amp; <i>p</i>);</ins>
};
</pre></blockquote>

<p>...</p>

<blockquote><pre>
pair(const T1&amp; <i>x</i>, const T2&amp; <i>y</i>);
</pre></blockquote>

<p>
-3- <i>Effects:</i> The constructor initializes <tt>first</tt> with <i>x</i> and
<tt>second</tt> with <i>y</i>.
</p>

<blockquote><pre>
<ins>
template&lt;class <i>U</i>, class <i>V</i>&gt; pair(<i>U</i>&amp;&amp; <i>x</i>, <i>V</i>&amp;&amp; <i>y</i>);
</ins>
</pre></blockquote>

<p><ins>
-4- <i>Effects:</i> The constructor initializes <tt>first</tt> with
<tt>forward&lt;<i>U</i>&gt;(<i>x</i>)</tt> and <tt>second</tt> with
<tt>forward&lt;<i>V</i>&gt;(<i>y</i>)</tt>.
</ins></p>

<blockquote><pre><ins>
pair(pair&amp;&amp; <i>p</i>);
</ins></pre></blockquote>

<p><ins>
-5- <i>Effects:</i> The constructor initializes <tt>first</tt> with
<tt>move(<i>p.first</i>)</tt> and <tt>second</tt> with
<tt>move(<i>p.second</i>)</tt>.
</ins></p>

<blockquote><pre><ins>
template&lt;class <i>U</i>, class <i>V</i>&gt; pair(pair&lt;<i>U</i>, <i>V</i>&gt;&amp;&amp; <i>p</i>);
</ins></pre></blockquote>

<p><ins>
-6- <i>Effects:</i> The constructor initializes <tt>first</tt> with
<tt>move(<i>p.first</i>)</tt> and <tt>second</tt> with
<tt>move(<i>p.second</i>)</tt>.
</ins></p>

<blockquote><pre><ins>
pair&amp; operator=(pair&amp;&amp; <i>p</i>);
</ins></pre></blockquote>

<p><ins>
-7- <i>Effects:</i> Assigns <tt>first</tt> with <tt>move(<i>p.first</i>)</tt>
and <tt>second</tt> with <tt>move(<i>p.second</i>)</tt>.
</ins></p>

<p><ins>
-8- <i>Returns:</i> <tt>*this</tt>.
</ins></p>

<blockquote><pre><ins>
template&lt;class <i>U</i>, class <i>V</i>&gt; pair&amp; operator=(pair&lt;<i>U</i>, <i>V</i>&gt;&amp;&amp; <i>p</i>);
</ins></pre></blockquote>

<p><ins>
-9- <i>Effects:</i> Assigns <tt>first</tt> with <tt>move(<i>p.first</i>)</tt>
and <tt>second</tt> with <tt>move(<i>p.second</i>)</tt>.
</ins></p>

<p><ins>
-10- <i>Returns:</i> <tt>*this</tt>.
</ins></p>

<blockquote><pre>
template&lt;class <i>U</i>, class <i>V</i>&gt; pair(const pair&lt;<i>U</i>, <i>V</i>&gt;&amp; <i>p</i>);
</pre></blockquote>

<p>
-<del>4</del> <ins>11</ins>- <i>Effects:</i> Initializes members from the
corresponding members of the argument, performing implicit conversions as
needed.
</p>

<blockquote><pre><ins>
void swap(pair&amp;&amp; <i>p</i>);
</ins></pre></blockquote>

<p><ins>
-12- <i>Effects:</i>  Swaps <tt>first</tt> with <tt>p.first</tt> and
<tt>second</tt> with <tt>p.second</tt>.
</ins></p>

<p><ins>
-13- <i>Requires:</i>  <tt>first_type</tt> and <tt>second_type</tt> must be
<tt>Swappable</tt>.
</ins></p>

<p>...</p>

<p>
-<del>6</del> <ins>15</ins>Returns: <tt>x.first &lt; y.first || (!(y.first &lt;
x.first) &amp;&amp; x.second &lt; y.second)</tt>.
</p>

<blockquote><pre><ins>
template &lt;class T1, class T2&gt;
  void swap(pair&lt;T1,T2&gt;&amp; <i>x</i>, pair&lt;T1,T2&gt;&amp; <i>y</i>);
template &lt;class T1, class T2&gt;
  void swap(pair&lt;T1,T2&gt;&amp;&amp; <i>x</i>, pair&lt;T1,T2&gt;&amp; <i>y</i>);
template &lt;class T1, class T2&gt;
  void swap(pair&lt;T1,T2&gt;&amp; <i>x</i>, pair&lt;T1,T2&gt;&amp;&amp; <i>y</i>);
</ins></pre></blockquote>

<p><ins>
-16- <i>Effects:</i> <tt><i>x</i>.swap(<i>y</i>)</tt>
</ins></p>

<h2><a name="20.4 - Memory"></a>20.4 - Memory</h2>

<blockquote class="note">
<p>
There are three changes for section 20.4: </p>

<ol>
<li>Add a <tt>construct</tt> member function to the default allocator.</li>
<li>Deprecate <tt>auto_ptr</tt>.</li>
<li>Add <tt>unique_ptr</tt> to replace the functionality provided by <tt>auto_ptr</tt>.</li>
</ol>

</blockquote>

<p>
In the <tt>&lt;memory&gt;</tt> synopsis delete:
</p>

<blockquote><pre>
<del>template&lt;class X&gt; class auto_ptr;</del>
</pre></blockquote>

<p>
and add at the same place:
</p>

<blockquote><pre>
<ins>template&lt;class X&gt; class unique_ptr;</ins>
</pre></blockquote>

<h3><a name="20.4.1 - The default allocator"></a>20.4.1 - The default allocator</h3>

<blockquote class="note">
<p>
The changes below simply implement for the default allocator the updated
allocator requirements as
previously discussed in <a href="#20.1.10 - Allocator requirements">section
20.1.10</a>.
</p>
</blockquote>

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

  allocator() throw();
  allocator(const allocator&amp;) throw();
  template &lt;class U&gt; allocator(const allocator&lt;U&gt;&amp;) throw();
  ~allocator() throw();

  pointer address(reference x) const;
  const_pointer address(const_reference x) const;

  pointer allocate(
    size_type, allocator&lt;void&gt;::const_pointer hint = 0);
  void deallocate(pointer p, size_type n);
  size_type max_size() const throw();

  void construct(pointer p, const T&amp; val);
  <ins>template &lt;class U&gt; void construct(pointer p, U&amp;&amp; val);</ins>
  void destroy(pointer p);
};
</pre></blockquote>

<p>...</p>

<blockquote><pre><ins>
<tt>template &lt;class U&gt; void construct(pointer p, U&amp;&amp; val);</tt>
</ins></pre></blockquote>

<p><ins>
-13- <i>Effects:</i> <tt>::new((void*)p) T(std::forward&lt;U&gt;(val))</tt>
</ins></p>

<h3><a name="20.4.5 - Class template auto_ptr"></a>20.4.5 - Class template auto_ptr</h3>

<blockquote class="note">
<p>
<b>Why deprecate <tt>auto_ptr</tt>?</b>
</p>

<p>
The <tt>auto_ptr</tt> class template was a pioneer in the area of move
semantics. <tt>auto_ptr</tt> has always had move semantics - the ability to
transfer its resource from one object to another.  An early <tt>auto_ptr</tt>
design accomplished this transfer using copy syntax and with a <tt>const
auto_ptr</tt> as the source: </p>

<blockquote><pre>
const auto_ptr&lt;int&gt; source(new int);
auto_ptr&lt;int&gt; target = source;  // move from const source to target
</pre></blockquote>

<p>
With such a design, one could put <tt>auto_ptr</tt> into a container: </p>

<blockquote><pre>
vector&lt;auto_ptr&lt;int&gt; &gt; vec;
</pre></blockquote>

<p>
However field experience with this design revealed subtle problems.  Namely:
</p>

<blockquote><pre>
sort(vec.begin(), vec.end(), indirect_less());
</pre></blockquote>

<p>
Depending upon the implementation of sort, the above line of reasonable looking
code
may or may not execute as expected, and may even <strong>crash</strong>!  The
problem is that some implementations of <tt>sort</tt>
will pick an element out of the sequence, and store a local <em>copy</em> of it.
</p>

<blockquote><pre>
...
value_type pivot_element = *mid_point;
...
</pre></blockquote>

<p>
The algorithm assumed that after this construction that <tt>pivot_element</tt>
and <tt>*mid_point</tt> were equivalent.  However when <tt>value_type</tt>
turned out to be an <tt>auto_ptr</tt>, this assumption failed, and subsequently
so did the algorithm. </p>

<p>
The fix to this problem was to make <tt>auto_ptr</tt> inhospitable to containers
by disallowing "copying" from a <tt>const auto_ptr</tt>.  With such an
<tt>auto_ptr</tt>, one gets a compile time error if you try to put it in a
container. </p>

<p>
However that fix really only saves clients from sorting standard containers of
<tt>auto_ptr</tt>.  It does not prevent clients from sorting client-defined
containers of <tt>auto_ptr</tt>, or even built-in arrays <tt>auto_ptr</tt>. For
example the following code will compile today: </p>

<blockquote><pre>
#include &lt;algorithm&gt;
#include &lt;memory&gt;

struct indirect_less
{
    template &lt;class T&gt;
    bool operator()(const T& x, const T& y)
    {
        return *x &lt; *y;
    }
};

int main()
{
    std::auto_ptr&lt;int&gt; ptrs[3];
    ptrs[0].reset(new int(3));
    ptrs[1].reset(new int(2));
    ptrs[2].reset(new int(1));
    std::sort(ptrs, ptrs+3, indirect_less()); // run time error?!
}
</pre></blockquote>

<p>
Whether or not it runs correctly is entirely dependent upon the implementation
of <tt>std::sort</tt>.  And this does not represent a problem with
<tt>std::sort</tt>. Calling any generic code, whether <tt>std</tt> or not, that
will operate on <tt>auto_ptr</tt> is risky because the generic code may assume
that something
that looks like a copy operation, actually <em>is</em> a copy operation.
</p>

<p>
<b>Conclusion:</b>
</p>

<blockquote><p>
One should not move from lvalues using copy syntax.  Other syntax for moving
should be used instead. Otherwise generic code is likely to initiate a move when
a copy was intended. </p></blockquote>

<p>
<tt>auto_ptr</tt> moves from lvalues using copy syntax and is thus fundamentally
unsafe. </p>

</blockquote>

<p>
Copy section 20.4.5, in its entirety, to a new section, D.8, and title that
section: auto_ptr. Then modify section 20.4.5 as shown below to introduce
<tt>unique_ptr</tt>.
</p>

<h4><a name="Addition - Class template unqiue_ptr"></a>Addition - Class template unqiue_ptr</h4>

<blockquote class="note">

<h5>Covering auto_ptr functionality</h5>

<p>
Despite the fact that <tt>auto_ptr</tt> is fundamentally unsafe, we should not
just deprecate it without simultaneously providing the same functionality some
other way. <tt>auto_ptr</tt> may be unsafe, but it is also very useful,
especially for RAII handling of heap pointers. </p>

<p>
And this is the goal of <tt>unique_ptr</tt> proposed below.  <tt>unique_ptr</tt>
is intended as a safer <tt>auto_ptr</tt> replacement.  However because
<tt>unique_ptr</tt> does not move from lvalues with copy syntax, it is not a
100% source-compatible drop in replacement for <tt>auto_ptr</tt>.  If it were,
we could just fix <tt>auto_ptr</tt> instead of deprecating it and introducing a
new class template. </p>

<p>
It turns out that we can do much more than merely make <tt>unique_ptr</tt> a
safer <tt>auto_ptr</tt>.  The proposed <tt>unique_ptr</tt> offers significant
additional functionality over <tt>auto_ptr</tt> without adding space or time
overhead (unless such overhead is explicitly requested), and while maintaining
source compatibility with <tt>auto_ptr</tt> sans the ability to move from an
lvalue with copy syntax (but you can move from an lvalue with move syntax). </p>

<p>
Indeed, everything you can do with <tt>auto_ptr</tt>, <tt>unique_ptr</tt> will
do too, with the same syntax ... except for moving from lvalues: </p>

<blockquote><pre>
// default construct
auto_ptr&lt;int&gt;   ap;
unique_ptr&lt;int&gt; up;

// construct with pointer
auto_ptr&lt;int&gt;   ap(new int(1));
unique_ptr&lt;int&gt; up(new int(1));

// dereference
*ap = 2;
*up = 2;

// reset
ap.reset();
up.reset();
// etc.
</pre></blockquote>

<p>
And the <tt>sizeof(auto_ptr&lt;T&gt;) == sizeof(unique_ptr&lt;T&gt;)</tt>. </p>

<p>
However copy semantics is disabled with <tt>unique_ptr</tt>: </p>

<blockquote><pre>
auto_ptr&lt;int&gt; ap1(new int);
auto_ptr&lt;int&gt; ap2 = ap1;  // ok, but unsafe implicit move

unique_ptr&lt;int&gt; up1(new int);
unique_ptr&lt;int&gt; up2 = up1;  // compile time error: illegal access to
                            // private copy constructor
</pre></blockquote>

<p>
If you really want to transfer ownership from the lvalue <tt>unique_ptr</tt>,
you <tt>move</tt> from it just as you would any other type: </p>

<blockquote><pre>
unique_ptr&lt;int&gt; up1(new int);
unique_ptr&lt;int&gt; up2 = move(up1);  // ok, explicit move
</pre></blockquote>

<p>
The <tt>move</tt> helper function simply casts an lvalue to an rvalue (with zero
expense). </p>

<blockquote><pre>
template &lt;class T&gt;
inline
typename std::tr1::remove_reference&lt;T&gt;::type&amp;&amp;
move(T&amp;&amp; p)
{
    return p;
}
</pre></blockquote>

<p>
And <tt>unique_ptr</tt> is set up to move from rvalues with copy syntax using
the <i>move constructor</i> (which binds to rvalues), while blocking the copy
from lvalues by making the copy constructor (which binds to lvalues) private:
</p>

<blockquote><pre>
template &lt;class T&gt;
class unique_ptr
{
public:
    ...
    unique_ptr(unique_ptr&amp;&amp; u);     // rvalues bind here
    ...
private:
    unique_ptr(const unique_ptr&amp;);  // lvalues bind here
};
</pre></blockquote>

<p>
Therefore clients can move from rvalues just as they do with <tt>auto_ptr</tt>
(with copy syntax), and from lvalues using the <tt>move</tt> helper function.
Both expressions construct the target using the <i>move constructor</i>
(<tt>unique_ptr(unique_ptr&amp;&amp;)</tt>). </p>

<p>
<b>Corollary:</b>
</p>

<blockquote><p>
Even though it is unsafe to move from an lvalue with copy syntax, it is both
safe and desirable to move from an rvalue with copy syntax.  When an rvalue
binds to a function, that function has a <i>unique</i> reference to the rvalue
and thus can safely modify it. </p></blockquote>

<p>
Moving from rvalues with copy syntax comes in handy when returning a
<tt>unique_ptr</tt> from a function: </p>

<blockquote><pre>
unique_ptr&lt;int&gt;
factory(int i)
{
    return unique_ptr&lt;int&gt;(new int(i));
}
...
unique_ptr&lt;int&gt; up = factory(1);  // ok, safe to implicitly move from rvalues
</pre></blockquote>

<p>
When passing <tt>unique_ptr</tt> to a function which takes a <tt>unique_ptr</tt>
by value, then just like <tt>auto_ptr</tt> the pointer ownership will be
transferred to that function.  However unlike <tt>auto_ptr</tt> that transfer
will not happen implicitly from an lvalue.  But it will happen implicitly from
an rvalue.  This is safe because no one has a reference to the rvalue to notice
the change in its value.  For example: </p>

<blockquote><pre>
auto_ptr&lt;int&gt;
ap_factory(int i)
{
    return auto_ptr&lt;int&gt;(new int(i));
}

unique_ptr&lt;int&gt;
up_factory(int i)
{
    return unique_ptr&lt;int&gt;(new int(i));
}

void ap_sink(auto_ptr&lt;int&gt;);
void up_sink(unique_ptr&lt;int&gt;);

...

auto_ptr&lt;int&gt; ap = ap_factory(1);
ap_sink(ap);                  // ok, but unsafe implicit move
unique_ptr&lt;int&gt; up = up_factory(1);
up_sink(up);                  // compile time error - implicit move from lvalue
up_sink(move(up));            // explicit move ok
up_sink(up_factory(1));       // ok, implicit move from rvalue safe
</pre></blockquote>

<h5>Regaining auto_ptr functionality</h5>

<p>
<tt>auto_ptr</tt> was originally intended to allow for easy conversions between
base and derived types.  However recent changes to the standard result in
<tt>auto_ptr&lt;Base&gt;</tt> not cooperating as originally intended with
<tt>auto_ptr&lt;Dervied&gt;</tt>: </p>

<blockquote><pre>
struct B {virtual ~B() {}};
struct D : B {};

auto_ptr&lt;D&gt;
ap_factory()
{
    return auto_ptr&lt;D&gt;();
}

void ap_sink(auto_ptr&lt;B&gt;);

void test()
{
    auto_ptr&lt;B&gt; ap = ap_factory();  // error:
                                    // no suitable copy constructor
    ap_sink(ap_factory());   // error: no suitable copy constructor
}
</pre></blockquote>

<p>
This functionality is regained with <tt>unique_ptr</tt>.  There are no longer
complicated <tt>auto_ptr_ref</tt> conversions to navigate.  <tt>unique_ptr</tt>
simply uses straight-forward constructors to bind to rvalues of related
<tt>unique_ptr</tt> types. </p>

<blockquote><pre>
struct B {virtual ~B() {}};
struct D : B {};

unique_ptr&lt;D&gt;
up_factory()
{
    return unique_ptr&lt;D&gt;();
}

void up_sink(unique_ptr&lt;B&gt;);

void test()
{
    unique_ptr&lt;B&gt; up = up_factory();  // ok
    up_sink(up_factory());            // ok
}
</pre></blockquote>

<h5>Beyond auto_ptr</h5>

<p>
It turns out that <tt>unique_ptr</tt> can offer functionality far beyond what
<tt>auto_ptr</tt> can. </p>

<h6>Use with containers and algorithms</h6>

<p>
You can <em>safely</em> put <tt>unique_ptr</tt>
into containers.  If the containers move elements around internally instead of
copy them around (as proposed for the standard containers), <tt>unique_ptr</tt>
will work without problems.  If the container does use copy semantics for its
<tt>value_type</tt>, then the client will be notified immediately (at compile
time).  There is no chance of a run time error due to a move being mistaken for
a copy. </p>

<p>
Similarly you can safely use <tt>unique_ptr</tt> with the standard algorithms,
or with any generic code.  Either the generic code will use move semantics, and
<tt>unique_ptr</tt> will just work, or it will use copy semantics, and the
client will be notified at compile time of the error. </p>

<blockquote><pre>
vector&lt;unique_ptr&lt;int&gt; &gt; v;
v.push_back(unique_ptr&lt;int&gt;(new int(3)));  // load vector with unique_ptr's
v.push_back(unique_ptr&lt;int&gt;(new int(2)));
v.push_back(unique_ptr&lt;int&gt;(new int(1)));
sort(v.begin(), v.end(), indirect_less());  // sort, obtaining {1, 2, 3}
</pre></blockquote>

<h6>Custom Deleter</h6>

<p>
Additionally <tt>unique_ptr</tt> can be given a <i>statically bound</i> custom
deleter.  This is in contrast to <tt>shared_ptr</tt>'s <i>dynamically bound</i>
custom deleter.  The key characteristic of a statically bound custom deleter is
that space for it can be optimized away if the deleter is an "empty" class
(assuming support for the empty base optimization).  And of course the default
deleter is an empty class which simply calls delete. </p>

<blockquote><pre>
struct my_deleter
{
    template &lt;class T&gt;
    void operator()(T*) {}; // do nothing
};

int main()
{
    int i = 0;
    typedef unique_ptr&lt;int, my_deleter&gt; Ptr;
    Ptr p(&amp;i);  // can safely point to stack because deleter does nothing
    *p = 1;
    assert(i == 1);                       // *p refers to i
    assert(sizeof(Ptr) == sizeof(int*));  // zero overhead!
}
</pre></blockquote>

<p>
The space optimization for <tt>unique_ptr</tt>'s deleter can easily be
accomplished with a tool such as
<a
href="http://www.boost.org/libs/utility/compressed_pair.htm">boost::compressed_pair</a>.
</p>

<blockquote><pre>
template&lt;class T, class D = default_delete&lt;T&gt; &gt;
class unique_ptr
{
...
private:
    compressed_pair&lt;T*, D&gt; ptr_;  // exposition only
};
</pre></blockquote>

<p>
Note that simply deriving <tt>unique_ptr</tt> from its deallocator type is not a
valid implementation technique as the deallocator is allowed to be an ordinary
function pointer (which can not be derived from).  Indeed use of a function
pointer as a deallocator can be a quite powerful technique, allowing for
deallocators to point across shared library boundaries. </p>

<blockquote><pre>
typedef unique_ptr&lt;int, <b>void (*)(void*)</b>&gt; Ptr;
int* i = (int*)malloc(sizeof(int));
Ptr p(i, <b>free</b>); // deallocate pointer with std::free
</pre></blockquote>

<p>
Of course when a function pointer is used as the custom deleter for
<tt>unique_ptr</tt>, then the <tt>sizeof(unique_ptr)</tt> will swell
accordingly.  However this is a feature that you only pay for if you use. </p>

<h6>Reference Deleter</h6>

<p>
One can also specify an lvalue-reference to a deleter as the deleter type.  This
is especially handy in generic code when you need to temporarily, but
aggressively grab ownership of a pointer using a deleter you know nothing about.
For example: </p>

<blockquote><pre>
template&lt;class T, class D&gt;
class A
{
    ...
    void foo(T* p);
private:
    T* p_;
    D  deleter_;
    ...
};

// A::foo establishes ownership of p, but
// must acquire other resources to do so.  A local
// unique_ptr is used as an aid to hold on to p while
// those other resources are acquired.
template&lt;class T, class D&gt;
void
A&lt;T, D&gt;::foo(T* p)
{
    // Establish preliminary ownership without requiring
    // a copy of the deleter D
    std::unique_ptr&lt;T, <b>D&amp;</b>&gt; hold(p, deleter_);  // no throw
    // acquire resources                       // if throws,
    // ...                                     //    deleter_(p) executed
    // transfer ownership to A
    p_ = hold.release();                       // no throw
}
</pre></blockquote>

<p>
In this example a local <tt>unique_ptr</tt> establishes a hold on the pointer. A
<i>reference</i> to the deleter is passed to the <tt>unique_ptr</tt> so that
there is no chance that copying the deleter can throw, and so that if the latter
resource acquisition step <i>does</i> throw, any relevant state in <tt>A</tt>'s
deleter will be updated as that deleter deallocates <tt>p</tt>. </p>

<h6><tt>unique_ptr</tt> For Arrays</h6>

<p>
Often when people see a smart pointer with a customizable deleter, they think
this is how they might handle pointers to arrays (which require <tt>delete
[]</tt> as opposed to <tt>delete</tt>).  However a smart pointer to an array
should have a fundamentally different interface than a smart pointer to a single
object. </p>

<ul>
<li>
A smart pointer to a single object can support derived-to-base conversions while
a smart pointer to an array must not support such conversions (5.3.5p3).
</li>
<li>
A dereference operator for a single object makes sense, but for an array of
objects makes less sense since only the first object in the array would be
referenced.
</li>
<li>
An indexing operator for a single object makes little sense since the only valid
index would be 0.  However an indexing operator for an array of objects makes
sense. </li> </ul>

<p>
Therefore a <tt>unique_ptr</tt> to an array of objects should sport a slightly
different interface in addition to the <tt>delete []</tt> operation.  This is
handled by a partial specialization resulting in a very intuitive interface:
</p>

<blockquote><pre>
unique_ptr&lt;int<b>[]</b>&gt; ua(new int[3]);
ua[0] = 5;
ua[1] = 4;
ua[2] = 3;
</pre></blockquote>

<p>
By including the trailing "<tt>[]</tt>" after the type in the
<tt>unique_ptr</tt> declaration, one states that one desires the "array
interface" for the smart pointer (no dereference, no conversions, has indexing).
 Additionally the default deleter for this interface is <tt>delete []</tt>.
However it can be overridden in the same manner as shown for the non-array
variant of <tt>unique_ptr</tt>. </p>

<blockquote><pre>
struct my_deleter
{
    template &lt;class T&gt;
    void operator()(T*) {}; // do nothing

    template &lt;class T&gt;
    void operator()(T*, size_t) {}; // do nothing
};

int main()
{
    int ia[3] = {0};
    typedef unique_ptr&lt;int[], my_deleter&gt; Ptr;
    Ptr p(ia);
    p[2] = 5;
    assert(ia[2] == 5);
    assert(sizeof(Ptr) == sizeof(int*));
}
</pre></blockquote>

<p>
If the size of the array is known at compile time, that information can be
included in the type of the <tt>unique_ptr</tt> in the obvious way: </p>

<blockquote><pre>
unique_ptr&lt;int<b>[3]</b>&gt; ua(new int[3]);
ua[0] = 5;
ua[1] = 4;
ua[2] = 3;
</pre></blockquote>

<p>
This information may be used by the implementation for range checking the
indexing operator (though this is not required).  The size will also be passed
to the deleter as the second parameter when the pointer is deallocated.  The
default deleter ignores this information though. </p>

<h5>Knowing when to stop</h5>

<p>
The functionality shown so far adds no run time overhead.  Space overhead is
only added if the custom deleter is not an empty class.  Otherwise
<tt>unique_ptr</tt> has precisely the same overhead as <tt>auto_ptr</tt> which
has precisely the same overhead as a simple built-in pointer. </p>

<p>
Adding support for a dynamically bound deleter (like <tt>shared_ptr</tt>) would
incur space and time overhead which is not appropriate for <tt>unique_ptr</tt>,
and the functionality gained over just simply specifying an ordinary function
pointer  as a deleter is minimal. </p>

<p>
Adding support to store the size of the array in the run time length array
variant of <tt>unique_ptr</tt> would add a word of overhead that is often not
needed.  When it is needed, clients can easily build a higher level smart
pointer on top of <tt>unique_ptr</tt>.  The size could even be stored in a
custom deleter.  The point is that storing the size of the array requires
overhead, and it is easier for clients to add overhead than subtract it. </p>

<p>
Thus <tt>unique_ptr</tt> is a minimalist smart pointer design - a solid
foundation upon which further work can be built. </p>

</blockquote>

<p><b>20.4.5 Class template</b> <del>auto_ptr</del> <ins>unique_ptr</ins></p>

<p><b>Synopsis</b></p>

<blockquote><pre>
namespace std {

template &lt;class T&gt; struct default_delete;
template &lt;class T&gt; struct default_delete&lt;T[]&gt;;
template &lt;class T, size_t N&gt; struct default_delete&lt;T[N]&gt;;

template&lt;class T, class D = default_delete&lt;T&gt; &gt; class unique_ptr;
template&lt;class T, class D&gt; class unique_ptr&lt;T[], D&gt;;
template&lt;class T, class D, size_t N&gt; class unique_ptr&lt;T[N], D&gt;;

template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;  x, unique_ptr&lt;T,D&gt;&amp;  y);
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;&amp; x, unique_ptr&lt;T,D&gt;&amp;  y);
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;  x, unique_ptr&lt;T,D&gt;&amp;&amp; y);

template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator==(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator!=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator &lt;(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator &gt;(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&gt;=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);

}  // namespace std
</pre></blockquote>

<p>
-1- Template <tt>unique_ptr</tt> stores a pointer to an object and deletes that
object using the associated deleter when it itself is destroyed (such as when
leaving block scope 6.7).
</p>

<p>
-2-  The <tt>unique_ptr</tt> provides a semantics of strict ownership. A
<tt>unique_ptr</tt> owns the object it holds a pointer to. A <tt>unique_ptr</tt>
is not <tt>CopyConstructible</tt>, nor <tt>CopyAssignable</tt>, however it is
<tt>MoveConstructible</tt> and <tt>MoveAssignable</tt>. [<i>Note:</i> The uses
of <tt>unique_ptr</tt> include providing exception-safety for dynamically
allocated memory, passing ownership of dynamically allocated memory to a
function, and returning dynamically allocated memory from a function. <i>--end
note</i>]
</p>

<p><b>20.4.5.1 Default deleters</b></p>

<blockquote><pre>
template &lt;class T&gt;
struct default_delete
{
    default_delete();
    template &lt;class U&gt;
        default_delete(const default_delete&lt;U&gt;&amp;);
    void operator() (T* ptr) const;
};
</pre></blockquote>

<blockquote><pre>
default_delete();
</pre></blockquote>

<p>
-1- <i>Effects:</i> Default constructs a <tt>default_delete</tt>.
</p>

<blockquote><pre>
template &lt;class U&gt;
    default_delete(const default_delete&lt;U&gt;&amp;);
</pre></blockquote>

<p>
-2- <i>Effects:</i> Constructs a <tt>default_delete&lt;T&gt;</tt> from a
<tt>default_delete&lt;U&gt;</tt>.
</p>

<blockquote><pre>
void operator() (T* ptr) const;
</pre></blockquote>

<p>
-3- <tt>operator()</tt> calls <tt>delete</tt> on <tt>ptr</tt>.  A diagnostic is
required if <tt>T</tt> is an incomplete type.
</p>

<blockquote><pre>
template &lt;class T&gt;
struct default_delete&lt;T[]&gt;
{
    void operator() (T* ptr) const;
};
</pre></blockquote>

<blockquote><pre>
void operator() (T* ptr) const;
</pre></blockquote>

<p>
-4- <tt>operator()</tt> calls <tt>delete []</tt> on <tt>ptr</tt>.  A diagnostic
is required if <tt>T</tt> is an incomplete type.
</p>

<blockquote><pre>
template &lt;class T, size_t N&gt;
struct default_delete&lt;T[N]&gt;
{
    void operator() (T* ptr, size_t) const;
};
</pre></blockquote>

<blockquote><pre>
void operator() (T* ptr, size_t) const;
</pre></blockquote>

<p>
-5- <tt>operator()</tt> calls <tt>delete []</tt> on <tt>ptr</tt>.  A diagnostic
is required if <tt>T</tt> is an incomplete type.  The <tt>size_t</tt> parameter
is ignored.
</p>

<p><b>20.4.5.2 <tt>unique_ptr</tt> for non-array objects</b></p>

<blockquote><pre>
template&lt;class T, class D = default_delete&lt;T&gt; &gt;
class unique_ptr
{
public:
    typedef T element_type;
    typedef D deleter_type;

    // constructors
    unique_ptr();
    explicit unique_ptr(T* p);
    unique_ptr(T* p, <i>implementation defined (see description below)</i> d);
    unique_ptr(T* p, <i>implementation defined (see description below)</i> d);
    unique_ptr(unique_ptr&amp;&amp; u);
    template &lt;class U, class E&gt;
        unique_ptr(unique_ptr&lt;U, E>&amp;&amp; u);

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr&amp; operator=(unique_ptr&amp;&amp; u);
    template &lt;class U, class E&gt;
        unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u);
    unique_ptr&amp; operator=(<i>unspecified-pointer-type</i>);

    // observers
    T&amp; operator*() const;
    T* operator->() const;
    T* get() const;
    deleter_type&amp;       get_deleter();
    const deleter_type&amp; get_deleter() const;
    operator <i>unspecified-bool-type</i>() const;

    // modifiers
    T* release();
    void reset(T* p = 0);
    void swap(unique_ptr&amp;&amp; u);

private:
    // disable copy from lvalue
    unique_ptr(const unique_ptr&amp;);
    template &lt;class U, class E&gt; unique_ptr(const unique_ptr&lt;U, E&gt;&amp;);
    unique_ptr&amp; operator=(const unique_ptr&amp;);
    template &lt;class U, class E&gt; unique_ptr&amp; operator=(const unique_ptr&lt;U, E&gt;&amp;);
};
</pre></blockquote>

<p>
-1- The default type for the template parameter <tt>D</tt> is
<tt>default_delete</tt>.  A client-supplied template argument <tt>D</tt> must be
a function pointer or functor for which given a value <tt>d</tt> of type
<tt>D</tt>, and a pointer <tt>ptr</tt> of type <tt>T*</tt>, the expression
<tt>d(ptr)</tt> is valid and has the effect of deallocating the pointer as
appropriate for that deleter.  <tt>D</tt> may also be an lvalue-reference to a
deleter.
</p>

<p>
-2- It is intended that if the deleter <tt>D</tt> maintains state, that this
state stay with the associated pointer as ownership is transferred from
<tt>unique_ptr</tt> to <tt>unique_ptr</tt>.  The deleter state need never be
copied, only moved or swapped as pointer ownership is moved around.  That is,
the deleter need only be <tt>MoveConstructible</tt>, <tt>MoveAssignable</tt> and
<tt>Swappable</tt>, and need not be <tt>CopyConstructible</tt> (unless copied
into the <tt>unique_ptr</tt>) nor <tt>CopyAssignable</tt>.
</p>

<p><b>20.4.5.2.1 <tt>unique_ptr</tt> constructors</b></p>

<blockquote><pre>
unique_ptr();
</pre></blockquote>

<p>
-1- <i>Requires:</i> <tt>D</tt> must be default constructible, and that
construction must not throw an exception.  <tt>D</tt> must not be a reference
type.
</p>

<p>
-2- <i>Effects:</i> Constructs a <tt>unique_ptr</tt> which owns nothing.
</p>

<p>
-3- <i>Postconditions:</i> <tt>get() == 0</tt>.  <tt>get_deleter()</tt> returns
a reference to a default constructed deleter <tt>D</tt>.
</p>

<p>
-4- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
unique_ptr(T* p);
</pre></blockquote>

<p>
-5- <i>Requires:</i> The expression <tt>D()(p)</tt> must be well formed.  The
default constructor of <tt>D</tt> must not throw an exception.  <tt>D</tt> must
not be a reference type.
</p>

<p>
-6- <i>Effects:</i> Constructs a <tt>unique_ptr</tt> which owns <tt>p</tt>.
</p>

<p>
-7- <i>Postconditions:</i> <tt>get() == p</tt>.  <tt>get_deleter()</tt> returns
a reference to a default constructed deleter <tt>D</tt>.
</p>

<p>
-8- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
unique_ptr(T* p, <i>implementation defined</i> d);
unique_ptr(T* p, <i>implementation defined</i> d);
</pre></blockquote>

<p>
-9- The signature of these constructors depends upon whether <tt>D</tt> is a
reference type or not.  If <tt>D</tt> is non-reference type <tt>A</tt>, then the
signatures are:
</p>

<blockquote><pre>
unique_ptr(T* p, const A& d);
unique_ptr(T* p, A&& d);
</pre></blockquote>

<p>
-10- If <tt>D</tt> is an lvalue-reference type <tt>A&</tt>, then the signatures
are:
</p>

<blockquote><pre>
unique_ptr(T* p, A& d);
unique_ptr(T* p, A&& d);
</pre></blockquote>

<p>
-11- If <tt>D</tt> is an lvalue-reference type <tt>const A&</tt>, then the
signatures are:
</p>

<blockquote><pre>
unique_ptr(T* p, const A& d);
unique_ptr(T* p, const A&& d);
</pre></blockquote>

<p>
-12- <i>Requires:</i> The expression <tt>d(p)</tt> must be well formed.
</p>

<p>
-13- If <tt>D</tt> is not an lvalue-reference type then
</p>

<ul>
<li>
If <tt>d</tt> is an lvalue or const rvalue then the first constructor of this
pair will be selected. <tt>D</tt> must be <tt>CopyConstructible</tt>, and this
<tt>unique_ptr</tt> will hold a copy of <tt>d</tt>.  The copy constructor of
<tt>D</tt> must not throw an exception.
</li>
<li>
Otherwise <tt>d</tt> is a non-const rvalue and the second constructor of this
pair will be selected.  <tt>D</tt> need only be <tt>MoveConstructible</tt>, and
this <tt>unique_ptr</tt> will hold a value <i>move constructed</i> from
<tt>d</tt>. The move constructor of <tt>D</tt> must not throw an exception.
</li>
</ul>

<p>
-14- Otherwise <tt>D</tt> is an lvalue-reference type.  <tt>d</tt> must be
reference-compatible with one of the constructors.  If <tt>d</tt> is an rvalue,
it will bind to the second constructor of this pair.  That constructor must
subsequently emit a diagnostic.  [<i>Note:</i> The diagnostic could be
implemented using a <tt>static_assert</tt> which assures that <tt>D</tt> is not
a reference type. <i>-- end note</i>]  Else <tt>d</tt> is an lvalue and will
bind to the first constructor of this pair.  The type which <tt>D</tt>
references need not be <tt>CopyConstructible</tt> nor
<tt>MoveConstructible</tt>.  This <tt>unique_ptr</tt> will hold a <tt>D</tt>
which refers to the lvalue <tt>d</tt>.  [<i>Note:</i> <tt>D</tt> may not be an
rvalue-reference type. <i>-- end note</i>]
</p>

<p>
-15- <i>Postconditions:</i> <tt>get() == p</tt>.  <tt>get_deleter()</tt> returns
a reference to the internally stored deleter.  If <tt>D</tt> is a reference type
then <tt>get_deleter()</tt> returns a reference to the lvalue <tt>d</tt>.
</p>

<p>
-16- <i>Throws:</i> nothing.
</p>

<p>[<i>Example:</i></p>
<blockquote><pre>
D d;
unique_ptr&lt;int, D&gt;        p1(new int, D()); // D must be MoveConstructible
unique_ptr&lt;int, D&gt;        p2(new int, d);   // D must be CopyConstructible
unique_ptr&lt;int, D&amp;&gt;       p3(new int, d);   // p3 holds a reference to d
unique_ptr&lt;int, const D&amp;&gt; p4(new int, D()); // Error, rvalue deleter object combined
                                            //    with reference deleter type
</pre></blockquote>
<p><i>--end example</i>]</p>

<blockquote><pre>
unique_ptr(const unique_ptr&);
</pre></blockquote>

<p>
-17- Declared private and left undefined to inhibit copy constructing from
lvalues and const rvalues.
</p>

<blockquote><pre>
unique_ptr(unique_ptr&& u);
</pre></blockquote>

<p>
-18- <i>Requires:</i> If the deleter is not a reference type, construction of
the deleter <tt>D</tt> from an rvalue <tt>D</tt> must not throw an exception.
</p>

<p>
-19- <i>Effects:</i> Constructs a <tt>unique_ptr</tt> which owns the pointer
which <tt>u</tt> owns (if any).  If the deleter is not a reference type, it is
move constructed from <tt>u</tt>'s deleter, otherwise the reference is copy
constructed from <tt>u</tt>'s deleter.  After the construction, <tt>u</tt> no
longer owns a pointer.  [<i>Note:</i> the deleter construction can be
implemented with <tt>forward&lt;D&gt;</tt>. <i>-- end note</i>]
</p>

<p>
-20- <i>Postconditions:</i> <tt>get() == </tt>value <tt>u.get()</tt> had before
the construction.  <tt>get_deleter()</tt> returns a reference to the internally
stored deleter which was constructed from <tt>u.get_deleter()</tt>.  If
<tt>D</tt> is a reference type then <tt>get_deleter()</tt> and
<tt>u.get_deleter()</tt> both reference the same lvalue deleter.
</p>

<p>
-21- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
template &lt;class U, class E&gt; unique_ptr(const unique_ptr&lt;U, E&gt;&amp;);
</pre></blockquote>

<p>
-22- Declared private and left undefined to inhibit copy constructing from
lvalues and const rvalues.
</p>

<blockquote><pre>
template &lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E>&amp;&amp; u);
</pre></blockquote>

<p>
-23- <i>Requires:</i> If <tt>D</tt> is not a reference type, construction of the
deleter <tt>D</tt> from an rvalue of type <tt>E</tt> must be well formed and not
throw an exception.  If <tt>D</tt> is a reference type, then <tt>E</tt> must be
the same type as <tt>D</tt> (diagnostic required).  <tt>U*</tt> must be
implicitly convertible to <tt>T*</tt>.
</p>

<p>
-24- <i>Effects:</i> Constructs a <tt>unique_ptr</tt> which owns the pointer
which <tt>u</tt> owns (if any).  If the deleter is not a reference type, it is
move constructed from <tt>u</tt>'s deleter, otherwise the reference is copy
constructed from <tt>u</tt>'s deleter.  After the construction, <tt>u</tt> no
longer owns a pointer.  [<i>Note:</i> the deleter construction can be
implemented with <tt>forward&lt;D&gt;</tt>. <i>-- end note</i>]
</p>

<p>
-25- <i>Postconditions:</i> <tt>get() == </tt>value <tt>u.get()</tt> had before
the construction, modulo any required offset adjustments resulting from the cast
from <tt>U*</tt> to <tt>T*</tt>.  <tt>get_deleter()</tt> returns a reference to
the internally stored deleter which was constructed from
<tt>u.get_deleter()</tt>.
</p>

<p>
-26- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.2.2 <tt>unique_ptr</tt> destructor</b></p>

<blockquote><pre>
~unique_ptr();
</pre></blockquote>

<p>
-1- <i>Effects:</i> If <tt>get() == 0</tt> there are no effects.  Otherwise
<tt>get_deleter()(get())</tt>.
</p>

<p>
-2- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.2.3 <tt>unique_ptr</tt> assignment</b></p>

<blockquote><pre>
unique_ptr&amp; operator=(const unique_ptr&amp;);
</pre></blockquote>

<p>
-1- Declared private and left undefined to inhibit copy assignment from lvalues
and const rvalues.
</p>

<blockquote><pre>
unique_ptr&amp; operator=(unique_ptr&amp;&amp; u);
</pre></blockquote>

<p>
-2- <i>Requires:</i>  Assignment of the deleter <tt>D</tt> from an rvalue
<tt>D</tt> must not throw an exception.
</p>

<p>
-3- <i>Effects:</i> <tt>reset(u.release())</tt> followed by a move assignment
from <tt>u</tt>'s deleter to this deleter.
</p>

<p>
-4- <i>Postconditions:</i> This <tt>unique_ptr</tt> now owns the pointer which
<tt>u</tt> owned, and <tt>u</tt> no longer owns it.  [<i>Note:</i> If <tt>D</tt>
is a reference type, then the referenced lvalue deleters are move assigned.
<i>-- end note</i>]
</p>

<p>
-5- <i>Returns:</i> <tt>*this</tt>.
</p>

<p>
-6- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
template &lt;class U, class E&gt; unique_ptr&amp; operator=(const unique_ptr&lt;U, E&gt;&amp;);
</pre></blockquote>

<p>
-7- Declared private and left undefined to inhibit copy assignment from lvalues
and const rvalues of convertible <tt>unique_ptr</tt> types.
</p>

<blockquote><pre>
template &lt;class U, class E&gt; unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u);
</pre></blockquote>

<p>
-8- <i>Requires:</i>  Assignment of the deleter <tt>D</tt> from an rvalue
<tt>E</tt> must not throw an exception.  <tt>U*</tt> must be implicitly
convertible to <tt>T*</tt>.
</p>

<p>
-9- <i>Effects:</i> <tt>reset(u.release())</tt> followed by a move assignment
from <tt>u</tt>'s deleter to this deleter.  If either <tt>D</tt> or <tt>E</tt>
is a reference type, then the referenced lvalue deleter participates in the move
assignment.
</p>

<p>
-10- <i>Postconditions:</i> This <tt>unique_ptr</tt> now owns the pointer which
<tt>u</tt> owned, and <tt>u</tt> no longer owns it.
</p>

<p>
-11- <i>Returns:</i> <tt>*this</tt>.
</p>

<p>
-12- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
unique_ptr&amp; operator=(<i>unspecified-pointer-type</i>);
</pre></blockquote>

<p>
-13- Assigns from the literal <tt>0</tt> or <tt>NULL</tt>.  [<i>Note:</i> The
<i>unspecified-pointer-type</i> is often implemented as a pointer to a private
data member, avoiding many of the implicit conversion pitfalls. <i>--end
note</i>]
</p>

<p>
-14- <i>Effects:</i> <tt>reset()</tt>.
</p>

<p>
-15- <i>Postconditions:</i> <tt>get() == 0</tt>.
</p>

<p>
-16- <i>Returns:</i> <tt>*this</tt>.
</p>

<p>
-17- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.2.4 <tt>unique_ptr</tt> observers</b></p>

<blockquote><pre>
T&amp; operator*() const;
</pre></blockquote>

<p>
-1- <i>Requires:</i> <tt>get() != 0</tt>.
</p>

<p>
-2- <i>Returns:</i> <tt>*get()</tt>.
</p>

<p>
-3- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
T* operator->() const;
</pre></blockquote>

<p>
-4- <i>Requires:</i> <tt>get() != 0</tt>.
</p>

<p>
-5- <i>Returns:</i> <tt>get()</tt>.
</p>

<p>
-6- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
T* get() const;
</pre></blockquote>

<p>
-7- <i>Returns:</i> The stored pointer.
</p>

<p>
-8- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
deleter_type&amp;       get_deleter();
const deleter_type&amp; get_deleter() const;
</pre></blockquote>

<p>
-9- <i>Returns:</i> A reference to the stored deleter.
</p>

<p>
-10- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
operator <i>unspecified-bool-type</i>() const;
</pre></blockquote>

<p>
-11- <i>Returns:</i> an unspecified value that, when used in boolean contexts,
is equivalent to <tt>get() != 0</tt>.
</p>

<p>
-12- <i>Throws:</i> nothing.
</p>

<p>
-13- [<i>Note:</i> The <i>unspecified-bool-type</i> is often implemented as a
pointer to a private data member, avoiding many of the implicit conversion
pitfalls. <i>--end note</i>]
</p>

<p><b>20.4.5.2.5 <tt>unique_ptr</tt> modifiers</b></p>

<blockquote><pre>
T* release();
</pre></blockquote>

<p>
-1- <i>Postconditions:</i> <tt>get() == 0</tt>.
</p>

<p>
-2- <i>Returns:</i> the value <tt>get()</tt> had at the start of the call to
<tt>release</tt>.
</p>

<p>
-3- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
void reset(T* p = 0);
</pre></blockquote>

<p>
-4- <i>Effects:</i> If <tt>p == get()</tt> there are no effects.  Otherwise
<tt>get_deleter()(get())</tt>.
</p>

<p>
-5- <i>Postconditions:</i> <tt>get() == p</tt>.
</p>

<p>
-6- <i>Throws:</i> nothing.
</p>

<blockquote><pre>
void swap(unique_ptr&amp;&amp; u);
</pre></blockquote>

<p>
-7- <i>Requires:</i> The deleter <tt>D</tt> is <tt>Swappable</tt> and will not
throw an exception under <tt>swap</tt>.
</p>

-8- <i>Effects:</i>  The stored pointers of <tt>this</tt> and <tt>u</tt> are exchanged.  The stored deleters are <tt>swap</tt>'d (unqualified).

<p>
-9- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.3 <tt>unique_ptr</tt> for array objects with a run time length</b></p>

<blockquote><pre>
template&lt;class T, class D&gt;
class unique_ptr&lt;T[], D&gt;
{
public:
    typedef T element_type;
    typedef D deleter_type;

    // constructors
    unique_ptr();
    explicit unique_ptr(T* p);
    unique_ptr(T* p, <i>implementation defined</i> d);
    unique_ptr(T* p, <i>implementation defined</i> d);
    unique_ptr(unique_ptr&amp;&amp; u);

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr&amp; operator=(unique_ptr&amp;&amp; u);
    unique_ptr&amp; operator=(<i>unspecified-pointer-type</i>);

    // observers
    T&amp; operator[](size_t i) const;
    T* get() const;
    deleter_type&amp;       get_deleter();
    const deleter_type&amp; get_deleter() const;
    operator <i>unspecified-bool-type</i>() const;

    // modifiers
    T* release();
    void reset(T* p = 0);
    void swap(unique_ptr&amp;&amp; u);

private:
    // disable copy from lvalue
    unique_ptr(const unique_ptr&amp;);
    unique_ptr&amp; operator=(const unique_ptr&amp;);
};
</pre></blockquote>

<p>
-1- A specialization for array types is provided with a slightly altered
interface.
</p>

<ul>
<li>
Conversions among different types of <tt>unique_ptr&lt;T[], D&gt;</tt> or to or
from the non-array form of <tt>unique_ptr</tt> are disallowed (diagnostic
required).
</li>

<li>
Pointers to types derived from <tt>T</tt> are rejected by the constructors, and
by <tt>reset</tt>.
</li>

<li>
The observers <tt>operator*</tt> and <tt>operator-&gt;</tt> are not provided.
</li>
<li>
The indexing observer <tt>operator[]</tt> is provided.
</li>

<li>
The default deleter will call <tt>delete []</tt>.
</li>
</ul>

<p>
-2- Descriptions are provided below only for member functions that have behavior
different from the primary template.
</p>

<p><b>20.4.5.3.1 <tt>unique_ptr</tt> constructors</b></p>

<blockquote><pre>
unique_ptr(T* p);
unique_ptr(T* p, <i>implementation defined</i> d);
unique_ptr(T* p, <i>implementation defined</i> d);
</pre></blockquote>

<p>
-1- These constructors behave the same as in the primary template except that
they do not accept pointer types which are convertible to <tt>T*</tt>.
[<i>Note:</i> One implementation technique is to create private templated
overloads of these members. <i>-- end note</i>]
</p>

<p><b>20.4.5.3.2 <tt>unique_ptr</tt> observers</b></p>

<blockquote><pre>
T&amp; operator[](size_t i) const;
</pre></blockquote>

<p>
-1- <i>Requires:</i> <tt>i &lt;</tt> the size of the array to which the stored
pointer points.
</p>

<p>
-2- <i>Returns:</i> <tt>get()[i]</tt>.
</p>

<p>
-3- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.3.3 <tt>unique_ptr</tt> modifiers</b></p>

<blockquote><pre>
void reset(T* p = 0);
</pre></blockquote>

<p>
-1- <i>Requires:</i> Does not accept pointer types which are convertible to
<tt>T*</tt> (diagnostic required). [<i>Note:</i> One implementation technique is
to create a private templated overload. <i>-- end note</i>]
</p>

<p>
-2- <i>Effects:</i> If <tt>p == get()</tt> there are no effects.  Otherwise
<tt>get_deleter()(get())</tt>.
</p>

<p>
-3- <i>Postconditions:</i> <tt>get() == p</tt>.
</p>

<p>
-4- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.4 <tt>unique_ptr</tt> for array objects with a compile time length</b></p>

<blockquote><pre>
template&lt;class T, class D, size_t N&gt;
class unique_ptr&lt;T[N], D&gt;
{
public:
    typedef T element_type;
    typedef D deleter_type;
    static const size_t size = N;

    // constructors
    unique_ptr();
    explicit unique_ptr(T* p);
    unique_ptr(T* p, <i>implementation defined</i> d);
    unique_ptr(T* p, <i>implementation defined</i> d);
    unique_ptr(unique_ptr&amp;&amp; u);

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr&amp; operator=(unique_ptr&amp;&amp; u);
    unique_ptr&amp; operator=(<i>unspecified-pointer-type</i>);

    // observers
    T&amp; operator[](size_t i) const;
    T* get() const;
    deleter_type&amp;       get_deleter();
    const deleter_type&amp; get_deleter() const;
    operator <i>unspecified-bool-type</i>() const;

    // modifiers
    T* release();
    void reset(T* p = 0);
    void swap(unique_ptr&amp;&amp; u);

private:
    // disable copy from lvalue
    unique_ptr(const unique_ptr&amp;);
    unique_ptr&amp; operator=(const unique_ptr&amp;);
};
</pre></blockquote>

<p>
-1- This specialization gives the array a length known at compile time.  There
are three differences between this specialization, and the specialization for
arrays of length not known until run time.
</p>

<ol>
<li>
The indexing observer behavior for <tt>i &gt;= N</tt> is undefined for
<tt>unique_ptr&lt;T[]&gt;</tt> and implementation defined for
<tt>unique_ptr&lt;T[N]&gt;</tt>.
</li>
<li>
The deleter is called with <tt>get_deleter()(get(), N)</tt> instead of
<tt>get_deleter()(get())</tt>.  Client-defined deleters may be able to make use
of this extra information.
</li>
<li>
The size of the array is available as a <tt>static const size_t</tt> named
<tt>size</tt>.
</li>
</ol>

<p>
-2- Descriptions are provided below only for member functions that have behavior
different from the <tt>unique_ptr&lt;T[]&gt;</tt> specialization.
</p>

<p><b>20.4.5.4.1 <tt>unique_ptr</tt> destructor</b></p>

<blockquote><pre>
~unique_ptr();
</pre></blockquote>

<p>
-1- <i>Effects:</i> If <tt>get() == 0</tt> there are no effects.  Otherwise
<tt>get_deleter()(get(), N)</tt>.
</p>

<p>
-2- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.4.2 <tt>unique_ptr</tt> observers</b></p>

<blockquote><pre>
T&amp; operator[](size_t i) const;
</pre></blockquote>

<p>
-1- If <tt>i &gt;= N</tt> the behavior is implementation defined.
</p>

<p>
-2- <i>Returns:</i> <tt>get()[i]</tt>.
</p>

<p>
-3- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.4.3 <tt>unique_ptr</tt> modifiers</b></p>

<blockquote><pre>
void reset(T* p = 0);
</pre></blockquote>

<p>
-1- <i>Requires:</i> Does not accept pointer types which are convertible to
<tt>T*</tt> (diagnostic required). [<i>Note:</i> One implementation technique is
to create a private templated overload. <i>-- end note</i>]
</p>

<p>
-2- <i>Effects:</i> If <tt>p == get()</tt> there are no effects.  Otherwise
<tt>get_deleter()(get(), N)</tt>.
</p>

<p>
-3- <i>Postconditions:</i> <tt>get() == p</tt>.
</p>

<p>
-4- <i>Throws:</i> nothing.
</p>

<p><b>20.4.5.5 <tt>unique_ptr</tt> specialized algorithms</b></p>

<blockquote><pre>
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;  x, unique_ptr&lt;T,D&gt;&amp;  y);
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;&amp; x, unique_ptr&lt;T,D&gt;&amp;  y);
template&lt;class T, class D&gt; void swap(unique_ptr&lt;T,D&gt;&amp;  x, unique_ptr&lt;T,D&gt;&amp;&amp; y);
</pre></blockquote>

<p>
-1- <i>Effects:</i> Calls <tt>x.swap(y)</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator==(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-2- <i>Returns:</i> <tt>x.get() == y.get()</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator!=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-3- <i>Returns:</i> <tt>x.get() != y.get()</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator &lt;(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-4- <i>Returns:</i> <tt>x.get() &lt; y.get()</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&lt;=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-5- <i>Returns:</i> <tt>x.get() &lt;= y.get()</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator &gt;(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-6- <i>Returns:</i> <tt>x.get()  &gt; y.get()</tt>.
</p>

<blockquote><pre>
template&lt;class T1, class D1, class T2, class D2&gt;
  bool operator&gt;=(const unique_ptr&lt;T1,D1&gt;&amp; x, const unique_ptr&lt;T2,D2&gt;&amp; y);
</pre></blockquote>

<p>
-7- <i>Returns:</i> <tt>x.get() &gt;= y.get()</tt>.
</p>

<h2><a name="Acknowledgments"></a>Acknowledgments</h2>

<p>
Much thanks to Jonathan Turkanis for some excellent recommendations for this
proposal.
</p>

</body>
</html>
