<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Specifying Pointer-Like Requirements (Revision 1)</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
</style>
</head><body>
<address style="text-align: left;">
Document number: N3073=10-0063<br>
Project: Programming Language C++, Library Working Group<br>
Authors: <a href="mailto:daniel.kruegler@googlemail.com">Daniel Krgler</a>, <a href="mailto:wb@fnal.gov">Walter E. Brown</a><br>
Date: 2010-03-12
</address>
<hr>
<h1 style="text-align: center;">Specifying Pointer-Like Requirements (Revision 1)</h1>

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

<p>
This paper attempts to resolve several issues relating to <tt>unique_ptr</tt>
and pointer-like species.
The approach suggested in this paper
is to introduce a new requirement set <tt>NullablePointer</tt>,
and to apply it where applicable within the standard library.
<p>
For more details regarding the rationale,
see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/N3025.html">N3025</a>.
<p>

<h2><a name="RevisionHistory"></a>Revision History</h2>

<p><b>N3073</b> - Revision 1</p>

<ul>
<li>Provide better wording that specify the general requirements for instantiations of the <tt>unique_ptr</tt> template.
</li>
<li>Replace <tt>Swappable</tt> requirements by new <em>swappable</em> requirements as of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/N3048.html">N3048</a>
</li>
<li>Fixes the resolution related to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#950">950</a>, because
	of a wrongly ordered list of requirements that describe the possible removal of some member functions from overload set
</li>
</ul>

<p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3025.html"><b>N3025</b></a> - Initial version</p>

<h2><a name="Resolved_Issues"></a>Issues Resolved</h2>
<p>
If accepted,
this proposal would resolve the following library issues:
</p>
<table border="1">
  <tr>
    <th>Number</th>
    <th>Description</th>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a></td>
    <td>Unique_ptr::pointer requirements underspecified</td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1293">1293</a></td>
    <td><tt>unique_ptr&lt;T[], D&gt;</tt> needs to get rid of <em>unspecified-pointer-type</em></td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1307">1307</a></td>
    <td><tt>exception_ptr</tt> and <tt>allocator</tt> pointers don't understand <tt>!=</tt></td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1135">1135</a></td>
    <td><tt>exception_ptr</tt> should support contextual conversion to <tt>bool</tt></td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#932">932</a></td>
    <td><tt>unique_ptr(pointer p)</tt> for pointer deleter types</td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#950">950</a></td>
    <td><tt>unique_ptr</tt> converting ctor shouldn't accept array form</td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#983">983</a></td>
    <td><tt>unique_ptr</tt> reference deleters should not be moved from</td>
  </tr>
  <tr>
    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1100">1100</a></td>
    <td><tt>auto_ptr</tt> to <tt>unique_ptr</tt> conversion</td>
  </tr>
</table>
<p>

<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>

<p>

<ol>
<li>
<i>Change [propagation] as indicated:
[The intent is to resolve issue
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1307">1307</a>,
because exception_ptr does not define the meaning of <tt>!=</tt>. Further-on an alternative solution of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1135">1135</a> is provided which delegates contextual conversion to <tt>bool</tt>
to the newly suggested <tt>NullablePointer</tt> requirements. Note that we cannot strike p. 4 completely, because the more general
<tt>NullablePointer</tt> requirements also support default construction that may produce an indeterminate value in the general
case (e.g. built-in pointers or pointers-to-member), but <tt>exception_ptr</tt> is a class type that is intended to produce a null value even for this kind
of creation.]</i>
<p>
<blockquote>
<p>
1 The type <tt>exception_ptr</tt> can be used to refer to an exception object.
<p>
2 <tt>exception_ptr</tt> shall <del>be <tt>DefaultConstructible</tt>, <tt>CopyConstructible</tt>, <tt>CopyAssignable</tt>, and <tt>EqualityComparable</tt>.
<tt>exception_ptr</tt>'s operations shall not throw exceptions</del> <ins>satisfy the <tt>NullablePointer</tt> requirements ([nullablepointer.requirements])</ins>.
<p>
3 Two <del>objects</del><ins>non-null values</ins> of type <tt>exception_ptr</tt> are equivalent and compare equal if and only if
they refer to the same exception.
<p>
4 The default constructor of <tt>exception_ptr</tt> produces the null value of the type. <del>The null value is
equivalent only to itself.</del>
<p>
5 <del>An object of type <tt>exception_ptr</tt> can be compared for equality with a null pointer constant and
assigned a null pointer constant. The effect shall be as if <tt>exception_ptr()</tt> had been used in place of
the null pointer constant.</del><ins><tt>exception_ptr</tt> shall not be implicitly convertible to any arithmetic, enumeration, or pointer type.</ins>
<p>
6 [ Note: An implementation might use a reference-counted smart pointer as <tt>exception_ptr</tt>. &mdash; end note ]
</blockquote>
</li>
<li>
<i>Add before the current [allocator.requirements] subclause the following new subclause of [utility.requirements]:
	[<strong> Editor's note: The symbol ?? is used as representative of the expected table number</strong>]</i>
<p>
<ins><b>20.2.2 <tt>NullablePointer</tt> requirements [nullablepointer.requirements]</b></ins>
<p>
<ins>A <tt>NullablePointer</tt> type is a pointer-like type
that supports null values.
A type <tt>P</tt> meets the <tt>NullablePointer</tt> requirements if:</ins>
<ul>
<li><ins><tt>P</tt> satisfies the requirements of <tt>EqualityComparable</tt>, <tt>DefaultConstructible</tt>, <tt>CopyConstructible</tt>,
<tt>CopyAssignable</tt>, and <tt>Destructible</tt> ([utility.arg.requirements]), and lvalues of this type are 
swappable ([swappable.requirements]);</ins>
</li>
<li><ins>the expressions shown in Table ?? are valid and have the indicated semantics; and</ins>
</li>
<li><ins><tt>P</tt> also satisfies all other requirements of this subclause [nullablepointer.requirements]</ins>
</li>
</ul>
<p>
<ins>A value-initialized object of <tt>P</tt> produces the null value of the type. The null value shall be equivalent
only to itself. A default-initialized object of <tt>P</tt> may have an indeterminate value. [<em>Note</em>: Operations
involving indeterminate values may trigger undefined behavior. &mdash; <em>end note</em>]</ins>
<p>
<ins>An object <tt>p</tt> of <tt>P</tt> can be contextually converted to <tt>bool</tt> ([conv]). The effect shall be as if
<tt>p != nullptr</tt> had been evaluated in place of <tt>p</tt>.</ins>
<p>
<ins>No operation which is part of the <tt>NullablePointer</tt> requirements shall exit via an exception.</ins>
<p>
<ins>In Table ??, <tt>u</tt> denotes an identifier, <tt>t</tt> denotes a non-<tt>const</tt> lvalue of type <tt>P</tt>, <tt>a</tt> and
<tt>b</tt> denote values of type (possibly <tt>const</tt>) <tt>P</tt>, and <tt>np</tt> denotes a value of type
(possibly <tt>const</tt>) <tt>std::nullptr_t</tt>.</ins>
</p>
<blockquote>
<table border="1">
<caption><ins>Table ?? &mdash; Additional <tt>NullablePointer</tt> requirements</ins></caption>

<tbody>
<tr>
<th><ins>Expression</ins></th>
<th><ins>Return type</ins></th>
<th><ins>Operational semantics</ins></th>
</tr>

<tr>
<td><ins><tt>P u(np);</tt><br><tt>P u = np;</tt></ins></td>
<td></td>
<td><ins>post: <tt>u == nullptr</tt></ins></td>
</tr>
<tr>
<td><ins><tt>P(np)</tt></ins></td>
<td></td>
<td><ins>post: <tt>P(np) == nullptr</tt></ins></td>
</tr>
<tr>
<td><ins><tt>t = np</tt></ins></td>
<td><ins><tt>P&amp</tt></ins></td>
<td><ins>post: <tt>t == nullptr</tt></ins></td>
</tr>
<tr>
<td><ins><tt>a != b</tt></ins></td>
<td><ins>contextually convertible to <tt>bool</tt></ins></td>
<td><ins><tt>!(a == b)</tt></ins></td>
</tr>
<tr>
<td><ins><tt>a == np</tt><br><tt>np == a</tt></ins></td>
<td><ins>contextually convertible to <tt>bool</tt></ins></td>
<td><ins><tt>a == P()</tt></ins></td>
</tr>
<tr>
<td><ins><tt>a != np</tt><br><tt>np != a</tt></ins></td>
<td><ins>contextually convertible to <tt>bool</tt></ins></td>
<td><ins><tt>!(a == np)</tt></ins></td>
</tr>

</tbody></table>
</blockquote>

</li>
<li>Change [unique.ptr]/1+2 as indicated: <i>[This provides more specific descriptions of the general requirements
	for all instantiations of <tt>unique_ptr</tt>]</i>
<p>
1 <del>Template <tt>unique_ptr</tt></del>
<ins>A <em>unique pointer</em>
provides strict ownership semantics,
owning the object to which it holds a pointer.
More precisely,
a unique pointer is an object <em>u</em> that</ins> stores a
pointer to a<del>n</del> <ins>second</ins> object <ins><em>p</em></ins>
and <ins>that</ins><del>deletes that object</del>
<ins>will dispose of <em>p</em></ins>
<del>using the associated deleter</del>
when <del>it</del><ins><em>u</em></ins> is itself destroyed
(such as when leaving block scope (6.7)).
<ins>In this context, <em>u</em> is said to <em>own p</em>.</ins>
<p>
<ins>
2
The mechanism by which <em>u</em> disposes of <em>p</em> is known as <em>p</em>'s associated <em>deleter</em>,
a function object whose correct invocation results in <em>p</em>'s appropriate disposition (typically, its deletion).</ins>
<p>
<ins>
3
Let the notation <em>u.p</em> denote the pointer stored by <em>u</em>,
and let <em>u.d</em> denote the associated deleter.
Upon request,
<em>u</em> can <em>reset</em> (replace) <em>u.p</em> and <em>u.d</em>
with another pointer and deleter,
but must properly dispose of its owned object
via the associated deleter
before such replacement is considered completed.</ins>
<p>
<ins>
4
Additionally,
<em>u</em> can upon request <em>transfer ownership</em>
to another unique pointer <em>u2</em>.
Upon completion of such a transfer,
the following postconditions hold:
</ins>
<ul>
<li><ins><em>u2.p</em> is equal to the pre-transfer <em>u.p</em>, and</ins>
<li><ins><em>u.p</em><tt> == nullptr</tt>, and</ins>
<li><ins>if the pre-transfer <em>u.d</em> maintains state,
     such state has been transferred to <em>u2.d</em>.</ins>
</ul>
<p>
<ins>
As in the case of a reset,
<em>u2</em> must properly dispose of its pre-transfer owned object
via the pre-transfer associated deleter
before the ownership transfer is considered completed.
[<em>Note</em>: A deleter's state need never be copied,
only moved or swapped as ownership is transferred.
&mdash <em>end note</em> ]</ins>
</p>
<p>
5 <del>The <tt>unique_ptr</tt> provides a semantics of strict ownership.
A <tt>unique_ptr</tt> owns the object it holds a pointer to.</del>
<ins> Each object of a type <tt>U</tt>
instantiated from the <tt>unique_ptr</tt> template specified in this subclause
has the strict ownership semantics, specified above, of a unique pointer.
In partial achievement of these semantics,
each such <tt>U</tt></ins><del>A <tt>unique_ptr</tt></del> is
<del>not</del><ins>neither</ins> <tt>CopyConstructible</tt><del>,</del>
nor <tt>CopyAssignable</tt>,
however it is <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt>.
The template parameter <tt>T</tt> of <tt>unique_ptr</tt>
may be an incomplete type.
<p>
6
[<em>Note</em>: 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.
&mdash; <em>end note</em>]
</li>
<li>
<i>Add to [unique.ptr.single], class <tt>unique_ptr</tt> synopsis the following declarations: [This solves <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1100">1100</a>,
	but the wording needs some tweaking to take care of more general <tt>pointer</tt> types]</i>
<p>
<blockquote><pre>
template &lt;class T, class D = default_delete&lt;T&gt;&gt; class unique_ptr {
public:
    ...
    // constructors
    ...
    template &lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E&gt;&amp;&amp; u);
    <ins>template &lt;class U&gt; explicit unique_ptr(auto_ptr&lt;U&gt;&amp; u);</ins>
    <ins>template &lt;class U&gt; unique_ptr(auto_ptr&lt;U&gt;&amp;&amp; u);</ins>
    ...
};
</pre></blockquote>
</li>
<li>
<i>Change [unique.ptr.single] as indicated: [The intent is to replace the coupling between <tt>T*</tt> and the deleter's <tt>operator()</tt>
by a coupling between <tt>unique_ptr&lt;T, D&gt;::pointer</tt> and the deleter's <tt>operator()</tt>, see
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>. Another fix is related to requirements of the deleter:
It is unclear here, whether they are purely descriptive or normative. Since we specify the requirements on a per-member base, we can strike
this sentence here, but add the missing <tt>Destructible</tt> requirement.]
[<strong>Editor's note: p. 1 provides a resolution that is considered superior to that of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#870">870</a>, bullet 14 and should be applied instead of that.</strong>]</i>
<p>
<blockquote>
<p>
1 The default type for the template parameter <tt>D</tt> is <tt>default_delete</tt>. A client-supplied template argument for <tt>D</tt>
shall be a function <del>pointer or functor</del><ins>object type ([function.objects]), lvalue-reference to function, or
lvalue-reference to function object type</ins> for which, given a value <tt>d</tt> of type <tt>D</tt> and a <del>pointer</del><ins>value</ins>
<tt>ptr</tt> of type <tt><del>T*</del><ins>unique_ptr&lt;T, D&gt;::pointer</ins></tt>, the expression <tt>d(ptr)</tt> is valid and
has the effect of <del>deallocating</del> <ins>disposing of</ins> the pointer as appropriate for that deleter. <del><tt>D</tt> may also be an lvalue-reference to a deleter.</del>
<p>
2 <del>
If the deleter <tt>D</tt> maintains state, it is intended 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>.</del>
<ins>If the deleter's type <tt>D</tt> is not a reference type,
<tt>D</tt> shall satisfy the <tt>Destructible</tt>
requirements ([destructible]).</ins>
<p>
3 If the type <tt>remove_reference&lt;D&gt;::type::pointer</tt> exists, then <tt>unique_ptr&lt;T, D&gt;::pointer</tt> shall be a
synonym for <tt>remove_reference&lt;D&gt;::type::pointer</tt>. Otherwise <tt>unique_ptr&lt;T, D&gt;::pointer</tt> shall be
a synonym for <tt>T*</tt>. The type <tt>unique_ptr&lt;T, D&gt;::pointer</tt> shall <del>be <tt>CopyConstructible</tt> (Table 34) and
<tt>CopyAssignable</tt> (Table 36)</del><ins>satisfy the <tt>NullablePointer</tt> requirements ([nullablepointer.requirements])</ins>.
<p>
<ins>4 [Example:
Given an allocator type <tt>X</tt> ([allocator.requirements])
and letting the type <tt>A</tt> be a synonym for <tt>allocator_traits&lt;X&gt;</tt>,
the types
  <tt>A::pointer</tt>,
  <tt>A::const_pointer</tt>,
  <tt>A::void_pointer</tt>,
and
  <tt>A::const_void_pointer</tt>
may be used as <tt>unique_ptr&lt;T, D&gt;::pointer</tt>. &mdash; end example]</ins>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.ctor] as indicated: [The changes ensure that we now explicitly say, how the stored pointer and stored
	deleter are initialized, which is especially important for a <tt>constexpr</tt> function. Additionally we fix a language lapse
	here, because the term "default constructible" is not defined.
	(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>). Note that we solve <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#932">932</a>
as well]</i>
<blockquote>
<p>
    <tt>constexpr unique_ptr();</tt>
<blockquote><p>
        1 <em>Requires</em>: <tt>D</tt> shall <del>be default constructible</del><ins>satisfy the <tt>DefaultConstructible</tt> requirements</ins>,
            and that construction shall not throw an exception. <del><tt>D</tt> shall not be a reference type or pointer type (diagnostic required).</del>
<p>
        2 <em>Effects</em>: Constructs a <tt>unique_ptr</tt> which owns nothing<ins>, value-initializing the stored pointer and the stored
        	deleter</ins>.
<p>
        3 <em>Postconditions</em>:
          <ul>
          <li><tt>get() == <del>0</del><ins>nullptr</ins></tt>.
          <li><tt>get_deleter()</tt> returns a reference to <del>a
        	value-initialized</del><ins>the stored</ins> deleter<del> <tt>D</tt></del>.
          </ul>
<p>
	      4 <em>Throws</em>: nothing.
<p>
	      <ins>5 <em>Remarks</em>: If this constructor is instantiated with a pointer type or reference type argument for the template parameter <tt>D</tt>, the program is ill-formed.</ins>	            
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.ctor] as indicated: [This is a step-by-fix to ensure consistency to the changes of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2976.html">N2976</a>. Additionally we fix a language lapse
	here, because the term "default constructible" is not defined. (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>).
Note that we solve <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#932">932</a> as well]</i>
<blockquote>
<p>
    <tt>unique_ptr(pointer p);</tt>
<blockquote><p>
        5 <em>Requires</em>: <tt>D</tt> shall <del>be default constructible</del><ins>satisfy the <tt>DefaultConstructible</tt> requirements</ins>,
            and that construction shall not throw an exception.
<p>
        6 <em>Effects</em>: Constructs a <tt>unique_ptr</tt> which owns <tt>p</tt><ins>, initializing the stored pointer with <tt>p</tt>
        	and value-initializing the stored deleter</ins>.
<p>
        7 <em>Postconditions</em>:
          <ul>
          <li><tt>get() == p</tt>.
          <li><tt>get_deleter()</tt> returns a reference to <del>a default 
        	constructed</del><ins>the stored</ins> deleter<del> <tt>D</tt></del>.
          </ul>
<p>
	8 <em>Throws</em>: nothing.
<p>
	<ins>9 <em>Remarks</em>: If this constructor is instantiated
        with a pointer type or reference type
        for the template parameter <tt>D</tt>,
        the program is ill-formed.</ins>
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.ctor] as indicated: [The intent is to fix the current lack of specification
in which way the stored pointer is initialized (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>)
and to fix some wording impreciseness regarding deleter requirements.]</i>
<blockquote>
<p>
    <tt>unique_ptr(pointer p, <del><em>implementation-defined</em></del><ins><em>see below</em></ins> d1);</tt><br>
    <tt>unique_ptr(pointer p, <del><em>implementation-defined</em></del><ins><em>see below</em></ins> d2);</tt>
<blockquote><p>
	      <tt>...</tt>
<p>
	   12 <em>Requires</em>: If <tt>D</tt> is not an lvalue-reference type then
	   <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> <del>must be</del>
       <ins>shall satisfy the</ins> <tt>CopyConstructible</tt> <ins>requirements</ins> (Table 34), and this <tt>unique_ptr</tt> will hold a
       copy of <tt>d</tt>. The copy constructor of <tt>D</tt> shall 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> <del>need
      only be</del><ins>shall satisfy the</ins> <tt>MoveConstructible</tt> <ins>requirements</ins> (Table 33), and this <tt>unique_ptr</tt> will hold a value move constructed
      from <tt>d</tt>. The move constructor of <tt>D</tt> shall not throw an exception.
	   </li>
	   </ul>
	   <p>
        <tt>...</tt>
<p>
        <ins><em>Effects</em>: Constructs a <tt>unique_ptr</tt> which owns <tt>p</tt>, initializing the stored pointer with <tt>p</tt> and initializing
        	the deleter as described above.</ins>
<p>
        14 <em>Postconditions</em>:
	    	<ul>
                <li><tt>get() == p</tt>.
                <li><tt>get_deleter()</tt> returns a reference
                    to the <del>internally</del> stored deleter.
                <li>If <tt>D</tt> is a reference type
                    then <tt>get_deleter()</tt> returns a reference
                    to the lvalue <tt>d</tt>.
	    	</ul>
</blockquote>      
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.ctor] as indicated: [The intent is to clarify that the moved-from source must contain a null pointer, there
	is no other choice left and to fix some wording impreciseness regarding deleter requirements. With the possibility of user-defined
	pointer-like types the implication does only exist, if those are built-in pointers. (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>). Note that we solve
	<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#950">950</a> modulo type-completeness constraints and
	<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#983">983</a> as well]</i>
<blockquote>
<p>
    <tt>unique_ptr(unique_ptr&amp;&amp; u);</tt>
<blockquote><p>
      16 <em>Requires</em>: If <del>the deleter</del>
         <ins><tt>D</tt></ins> is not a reference type,
         <ins><tt>D</tt> shall satisfy the <tt>MoveConstructible</tt> requirements.</ins>
         <del>c</del><ins>C</ins>onstruction of the deleter <del><tt>D</tt></del> from an rvalue <ins>of type</ins> <tt>D</tt> shall not throw an exception.
<p>
      17 <em>Effects</em>: Constructs a <tt>unique_ptr</tt> <ins>by transferring ownership from <tt>u</tt> to <tt>*this</tt></ins><del>which owns the pointer which <tt>u</tt> 
      	owns (if any)</del>. If <del>the deleter</del><ins><tt>D</tt></ins> is not a reference type, <del>it</del><ins>this deleter</ins> is move constructed 
      		from <tt>u</tt>'s deleter, otherwise the <del>reference</del><ins>this deleter</ins> is copy constructed from <tt>u</tt>'s deleter. <del>After the construction, 
      			<tt>u</tt> no longer owns a pointer.</del> [<em>Note</em>: The deleter constructor can be implemented with <tt>std::forward&lt;D&gt;</tt>. &mdash; <em>end note</em>]
<p>
      18 <em>Postconditions</em>:
        <ul>
        <li><tt>get()<del> ==</del></tt> <ins>yields the</ins> value <tt>u.get()</tt> <del>had</del><ins>yielded</ins> before the 
        	construction. <tt>get_deleter()</tt> returns a reference to the <del>internally</del> stored deleter <del>which</del><ins>that</ins> was 
        	constructed from <tt>u.get_deleter()</tt>.
        </li>
        <li>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.
        </li>
      </ul>
<p>
      19 - <em>Throws</em>: nothing.
<p>
</blockquote><p>
    <tt>template &lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E&gt;&amp;&amp; u);</tt>
<blockquote><p>
      20 - <em>Requires</em>: If <tt><del>D</del><ins>E</ins></tt> is not a reference type, construction of the deleter <del><tt>D</tt></del> from 
      an rvalue of type <tt>E</tt> shall be well formed and shall not throw an exception. <ins>Otherwise <tt>E</tt> is a reference type and 
      construction of the deleter from an lvalue of type <tt>E</tt> shall be well formed and shall not throw an exception.</ins><del>If <tt>D</tt> 
      is a reference type, then <tt>E</tt> shall be the same type as <tt>D</tt> (diagnostic required). <tt>unique_ptr&lt;U, E&gt;::pointer</tt> 
      shall be implicitly convertible to <tt>pointer</tt>. [<em>Note</em>: These requirements imply that <tt>T</tt> and <tt>U</tt> are complete 
      types. &mdash; <em>end note</em>]</del>
<p>
	    <ins>? - <em>Remarks</em>: This constructor shall not participate in overload resolution unless:</ins>
	    	<p>
	    	<ul>
	    	<li><ins><tt>unique_ptr&lt;U, E&gt;::pointer</tt> is implicitly convertible to <tt>pointer</tt>, and</ins></li>
	    	<li><ins><tt>U</tt> is not an array type, and</ins></li>
	    	<li><ins><tt>D</tt> is a reference type
                    and <tt>E</tt> is the same type as <tt>D</tt>,
                    or <tt>E</tt> is implicitly convertible to <tt>D</tt>.</ins>
                    </li>
	      </ul>
<p>
	    21 <em>Effects</em>: Constructs a <tt>unique_ptr</tt> <ins>by transferring ownership from <tt>u</tt> to <tt>*this</tt></ins><del>which 
	    	owns the pointer which <tt>u</tt> owns (if any)</del>. If <del>the deleter</del> <ins><tt>E</tt></ins> is not a reference type, <del>it</del><ins>this deleter</ins> is move constructed from <tt>u</tt>'s deleter, otherwise <del>the reference</del><ins>this deleter</ins>
      is copy constructed from u's <tt>deleter</tt>. <del>After the construction, <tt>u</tt> no longer owns a pointer.</del> [<em>Note</em>: The deleter constructor can be implemented with
      <tt>std::forward&lt;<del>D</del><ins>E</ins>&gt;</tt>. &mdash; <em>end note</em>]
<p>
      22 <em>Postconditions</em>:
        <ul>
        <li><tt>get() <del>==</del></tt> <ins>yields the</ins> value <tt>u.get()</tt> had <ins>yielded</ins> before the construction<del>, modulo any required offset adjustments
      resulting from the cast from <tt>unique_ptr&lt;U, E&gt;::pointer</tt> to <tt>pointer</tt></del>.
        <li><tt>get_deleter()</tt> returns a reference to the <del>internally</del> stored deleter <del>which</del><ins>that</ins> was constructed from <tt>u.get_deleter()</tt>.
        </ul>
<p>
	    23 <em>Throws</em>: nothing.
</blockquote>
</blockquote>
</li>
<li>
<i>At the end of [unique.ptr.single.ctor] add the following sequence of paragraphs. [This solves <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1100">1100</a>,
	additionally honoring the more general <tt>pointer</tt> concept and specifies some missing effects and post-condition details.]</i>
<p>
<blockquote><pre>
<ins>template &lt;class U&gt; explicit unique_ptr(auto_ptr&lt;U&gt;&amp; u);</ins>
<ins>template &lt;class U&gt; unique_ptr(auto_ptr&lt;U&gt;&amp;&amp; u);</ins>
</pre>
<ins><em>Effects</em>: Constructs a <tt>unique_ptr</tt>, initializing the stored pointer with <tt>u.release()</tt> and value-initializing the stored deleter.</ins>
<p>
<ins><em>Postconditions</em>:</ins>
         <ul>
         <li><ins><tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction.</ins></li>
	      <li><ins><tt>u.get() == nullptr</tt>.</ins></li>
        <li><ins><tt>get_deleter()</tt> returns a reference to the stored deleter.</ins></li>
        </ul>
<p>
<ins><em>Throws</em>: nothing.</ins>
<p>
<ins><em>Remarks</em>:
	These constructors shall not participate in overload resolution
        unless
        <tt>U*</tt> is implicitly convertible to <tt>pointer</tt> and <tt>D</tt> is the same type as <tt>default_delete&lt;T&gt;</tt>.
        </ins>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.dtor]/2 as indicated (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>~unique_ptr();</tt>
<blockquote><p>
	    1 <em>Requires</em>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
         and shall not throw exceptions. [<em>Note</em>: The use of <tt>default_delete</tt> requires <tt>T</tt> to be a complete
         type. &mdash; <em>end note</em>]
<p>
      2 <em>Effects</em>: If <tt>get() == <del>0</del><ins>nullptr</ins></tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
<p>
	    3 <em>Throws</em>: nothing.
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.asgn] as indicated: [The intent is to clarify that the moved-from source must contain a null pointer,
	there is no other choice left. With the possibility of user-defined pointer-like types the implication
	does only exist, if those are built-in pointers (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>). Note that we solve
	<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#950">950</a> modulo type-completeness constraints and
	<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#983">983</a> as well]:</i>
<blockquote>
<p>
    <tt>unique_ptr& operator=(unique_ptr&amp;&amp; u);</tt>
<blockquote><p>
	    1 <em>Requires</em>: <ins>If <tt>D</tt>
              is not a reference type,
              <ins><tt>D</tt> shall satisfy the <tt>MoveAssignable</tt>
	    	requirements and</ins> a</ins><del>A</del>ssignment of the deleter <del><tt>D</tt></del> from an rvalue <ins>of type</ins> <tt>D</tt> shall 
	    		not throw an exception. <ins>Otherwise <tt>D</tt> is a reference type, <ins> <tt>remove_reference&lt;D&gt;::type</tt> shall satisfy the
	    	<tt>CopyAssignable</tt> requirements,</ins> and assignment of the deleter from an lvalue of type <tt>D</tt> shall not throw an exception.</ins>
<p>
      2 <em>Effects</em>:
      <ins>Transfers ownership from <tt>u</tt> to <tt>*this</tt>
      as if by calling </ins><tt>reset(u.release())</tt>
      followed by a<ins>n</ins> <del>move</del> assignment
      from <del><tt>u</tt>'s deleter to this deleter</del><ins><tt>std::forward&lt;D&gt;(u.get_deleter())</tt></ins>.
<p>
      <del>3 <em>Postconditions</em>: This <tt>unique_ptr</tt> now owns the pointer which <tt>u</tt> owned, and <tt>u</tt> no longer owns
      it.</del> <del>[<em>Note</em>: If <tt>D</tt> is a reference type, then the referenced lvalue deleters are
    move assigned. &mdash; <em>end note</em>]</del>
<p>
	    4 <em>Returns</em>: <tt>*this</tt>.
<p>
	    5 <em>Throws</em>: nothing.
</blockquote><p>
    <tt>template &lt;class U, class E&gt; unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u);</tt>
<blockquote><p>
	    6 <em>Requires</em>:
            <ins>If <tt>E</tt> is not a reference type,
            a</ins><del>A</del>ssignment of the deleter <del><tt>D</tt></del>
	    from an rvalue <ins>of type <tt>E</tt></ins><del><tt>D</tt></del> <ins>shall be well-formed and</ins> shall not throw an exception. <ins>Otherwise <del>the
	    	deleter</del> <tt>E</tt> is a reference type,
                and assignment of the deleter <del><tt>D</tt></del>
                from an lvalue of type <tt>E</tt> <ins>shall be
	    	well-formed and</ins> shall not throw an exception.</ins>
                <del><tt>unique_ptr&lt;U, E&gt;::pointer</tt> shall be implicitly
	    	convertible to <tt>pointer</tt>.
                [<em>Note</em>: These requirements imply that
                <tt>T</tt> and <tt>U</tt> are complete
	    	types. &mdash; <em>end note</em>]</del>
<p>
 	    <ins>7 <em>Remarks</em>: This operator shall not participate in overload resolution unless:</ins>
	    	<p>
	    	<ul>
	    	<li><ins><tt>unique_ptr&lt;U, E&gt;::pointer</tt> is implicitly convertible to <tt>pointer</tt>, and</ins></li>
	    	<li><ins><tt>U</tt> is not an array type.</ins></li>
	      </ul>

<p>
      8 <em>Effects</em>:
      <ins>Transfers ownership from <tt>u</tt> to <tt>*this</tt>
      as if by calling </ins><tt>reset(u.release())</tt>
      followed by a<ins>n</ins> <del>move</del> assignment
      from <del><tt>u</tt>'s deleter to this deleter</del><ins><tt>std::forward&lt;D&gt;(u.get_deleter())</tt></ins>.
      <del>If either
<tt>D</tt> or <tt>E</tt> is a reference type, then the referenced lvalue deleter participates in the move assignment.</del>
<p>
      9 - <del><em>Postconditions</em>: This <tt>unique_ptr</tt> now owns the pointer which <tt>u</tt> owned, and <tt>u</tt> no longer owns
    it.</del>
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.asgn] before p. 11 and p. 12 as indicated: [The first change is a simple
	typo fix (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>)]:</i>
<blockquote>
<p>
    <tt>unique_ptr&amp; operator=(nullptr_t<del>}</del><ins>)</ins>;</tt>
<blockquote><p>
	    11 <em>Effects</em>: <tt>reset()</tt>.<p>
      12 <em>Postcondition</em>: <tt>get() == <del>0</del><ins>nullptr</ins></tt><p>
      13 <em>Returns</em>: <tt>*this</tt>.<p>
      14 <em>Throws</em>: nothing.
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.observers] as indicated (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>)
	[For details see the <a href="#Remarks">Remarks</a> section]:</i>
<blockquote>
<p>
    <tt>typename add_lvalue_reference&lt;T&gt;::type operator*() const;</tt>
<blockquote><p>
	    1 <em>Requires</em>: <tt>get() != <del>0</del><ins>nullptr</ins></tt>.
<p>
	    2 <em>Returns</em>: <tt>*get()</tt>.
<p>
      <del>3 <em>Throws</em>: nothing.</del>
</blockquote><p>
	  <tt>pointer operator->() const;</tt>
<blockquote><p>
      4 <em>Requires</em>: <tt>get() != <del>0</del><ins>nullptr</ins></tt>.
<p>
	    5 <em>Returns</em>: <tt>get()</tt>.
<p>
      6 <em>Throws</em>: nothing.
<p>
      7 <em>Note</em>: use typically requires that <tt>T</tt> be a complete type.
</blockquote><p>
	  <tt>explicit operator bool() const;</tt>
<blockquote><p>
      12 <em>Returns</em>: <tt>get() != <del>0</del><ins>nullptr</ins></tt>.<p>
      13 <em>Throws</em>: nothing.
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.modifiers]/1 as indicated (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>pointer release();</tt>
<blockquote><p>
    1 <em>Postcondition</em>: <tt>get() == <del>0</del><ins>nullptr</ins></tt>.<p>
    2 <em>Returns</em>: The value <tt>get()</tt> had at the start of the call to <tt>release</tt>.<p>
    3 <em>Throws</em>: nothing.
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.single.modifiers] as indicated: [The intent is to ensure that potentially user-defined swaps are
	used. The used specification is as fuzzy in regard to the meaning of the exact swap call as other parts of the standard. It is
	intended to make this clearer as a result of the solution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#524">524</a>.
	A side-step fix and harmonization with the specification of the deleter is realized. We don't need to add the <tt>Swappable</tt>
	requirement for <tt>pointer</tt>, because those are already part of the <tt>NullablePointer</tt> requirements, including no-throw
	requirements] (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>void swap(unique_ptr&amp; u);</tt>
<blockquote><p>
	  8 <em>Requires</em>: <del>The deleter</del> <tt><del>D</del><ins>get_deleter()</ins></tt> shall be <del><tt>Swappable</tt></del><ins>swappable 
	  	([swappable.requirements]),</ins> and shall not throw an exception under <tt>swap</tt>.
<p>
    9 <em>Effects</em>: <del>The stored pointers of <tt>this</tt> and <tt>u</tt> are exchanged. The stored deleters are swap'd
    (unqualified)</del><ins>Invokes <tt>swap</tt> on the stored pointers and on the stored deleters of <tt>*this</tt> and <tt>u</tt></ins>.
</blockquote>
</blockquote>
</li>
<li>
<i>Change [unique.ptr.runtime], class template <tt>unique_ptr&lt;T[], D&gt;</tt> synopsis as indicated (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1293">1293</a>)</i>
<blockquote><p>
  <tt>// assignment</tt><br>
  <tt>unique_ptr&amp; operator=(unique_ptr&amp;&amp; u);</tt><br>
  <tt>unique_ptr&amp; operator=(<del><em>unspecified-pointer-type</em></del><ins>nullptr_t</ins>);</tt>
</blockquote>      
</li>
<li>
<i>Change [unique.ptr.runtime.observers] as indicated [For details see the <a href="#Remarks">Remarks</a> section]
	(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>T&amp; operator[](size_t i) const;</tt>
<blockquote><p>
       1 <em>Requires</em>: <tt>i &lt;</tt> the size of the array to which the stored pointer points.<p>
       2 <em>Returns</em>: <tt>get()[i]</tt>.<p>
       <del>3 <em>Throws</em>: nothing.</del>      
</blockquote>      
</blockquote>
</li>
<li>
<i>Change [unique.ptr.runtime.modifiers]/1 as indicated (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>void reset(pointer p = pointer());</tt><br>
    <tt>void reset(nullptr_t p);</tt>
<blockquote><p>
       1 <em>Effects</em>: If <tt>get() == <del>0</del><ins>nullptr</ins></tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
</blockquote>
</blockquote>
</li>
<li>
<i><strong>Let [unique.ptr.special] remain unchanged</strong>: [Note that the relational operators are not part of the basic requirement
	set, and that we want to support <strong>mixed</strong> <tt>==</tt>, which is beyond the <tt>EqualityComparable</tt> requirements.
	For details see the <a href="#Remarks">Remarks</a> section.] (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>):</i>
<blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator==(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     2 <em>Returns</em>: <tt>x.get() == y.get()</tt>.
</blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator!=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     3 <em>Returns</em>: <tt>x.get() != y.get()</tt>.
</blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator&lt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     4 <em>Returns</em>: <tt>x.get() &lt; y.get()</tt>.
</blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator&lt;=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     5 <em>Returns</em>: <tt>x.get() &lt;= y.get()</tt>.
</blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator&gt;(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     6 <em>Returns</em>: <tt>x.get() &gt; y.get()</tt>.
</blockquote>
<p>
    <tt>template &lt;class T1, class D1, class T2, class D2&gt;<br>
  bool operator&gt;=(const unique_ptr&lt;T1, D1&gt;&amp; x, const unique_ptr&lt;T2, D2&gt;&amp; y);</tt>
<blockquote><p>
	     7 <em>Returns</em>: <tt>x.get() &gt;= y.get()</tt>.
</blockquote>
<p>
</blockquote>
</li>
<li>
<p>
<i>Change Table 40 &mdash; Allocator requirements as indicated: [All removed entries are already specified via the <tt>NullablePointer</tt> requirements]</i>
<p>
<blockquote>
<table border="1">
<caption>Table 40 &mdash; Allocator requirements</caption>

<tbody>
<tr>
<th>Expression</th>
<th>Return type</th>
<th>Assertion/note<br>pre-/post-condition</th>
<th>Default</th>
</tr>

<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>
<tr>
<td><del><tt>pointer d(nullptr)<br>
pointer d = nullptr<br>
const_pointer e(nullptr)<br>
const_pointer e = nullptr</tt></del></td>
<td></td>
<td><del><tt>d</tt> and <tt>e</tt> are null pointers
and need not be dereferenceable.<br>
<tt>static_cast&lt;bool&gt;(d) == false</tt>,<br>
<tt>static_cast&lt;bool&gt;(e) == false</tt></del></td>
<td></td>
</tr>
<tr>
<td><del><tt>void_pointer d(nullptr)<br>
void_pointer d = nullptr<br>
const_void_pointer e(nullptr)<br>
const_void_pointer e = nullptr</tt></del></td>
<td></td>
<td><del><tt>d</tt> and <tt>e</tt> are null pointers
and need not be dereferenceable.<br>
<tt>static_cast&lt;bool&gt;(d) == false</tt>,<br>
<tt>static_cast&lt;bool&gt;(e) == false</tt></del></td>
<td></td>
</tr>
<tr>
<td><del><tt>p</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>false</tt> only if <tt>p</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>q</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>false</tt> only if <tt>q</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>w</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>false</tt> only if <tt>w</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>z</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>false</tt> only if <tt>z</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>!p</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>true</tt> only if <tt>p</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>!q</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>true</tt> only if <tt>q</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>!w</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>true</tt> only if <tt>w</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><del><tt>!z</tt></del></td>
<td><del>contextually convertible to <tt>bool</tt></del></td>
<td><del><tt>true</tt> only if <tt>z</tt> is a null pointer</del></td>
<td></td>
</tr>
<tr>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
<td><tt>...</tt></td>
</tr>

</tbody></table>
</blockquote>
</li>
<li>
<p>
<i>Change [allocator.requirements]/4 as indicated [All removed parts are already specified via the <tt>NullablePointer</tt> requirements.
	This change additionally ensures that <tt>!=</tt> is now well-defined for the allocator pointer types and fixes therefore
	issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1307">1307</a>]</i>:
<p>
<blockquote>
<p>
The <tt>X::pointer</tt>, <tt>X::const_pointer</tt>, <tt>X::void_pointer</tt>, and <tt>X::const_void_pointer</tt> types shall satisfy
the <ins><tt>NullablePointer</tt></ins> requirements <ins>([nullablepointer.requirements])</ins><del>of <tt>EqualityComparable</tt>,
<tt>DefaultConstructible</tt>, <tt>CopyConstructible</tt>, <tt>CopyAssignable</tt>, <tt>Swappable</tt>, and <tt>Destructible</tt>
(20.2.1)</del>. No constructor, comparison operator, copy operation, move operation, or swap operation on these types shall exit via an
exception.<del>A default-initialized object may have a singular value. A value-initialized object shall compare equal to <tt>nullptr</tt></del>.
<tt>X::pointer</tt> and <tt>X::const_pointer</tt> shall also satisfy the requirements for a random access iterator (24.2).
</blockquote>
</li>
</ol>

<h2><a name="Remarks"></a>Remarks</h2>
<p>
During reviews of this paper it became controversial how to properly specify the operational semantics of <tt>operator*</tt>,
<tt>operator[]</tt>, and the heterogenous comparison functions. [structure.specifications]/3 doesn't clearly say whether a
<em>Returns</em> element (in the absence of the new <em>Equivalent to</em> formula) specifies effects. Further-on it's unclear
whether this would allow for such a return expression to exit via an exception, if additionally a <em>Throws:</em>-Nothing
element is provided (would the implementor be required to catch those?). To resolve this conflict, any existing <em>Throws</em>
element was removed for these operations, which is at least consistent with [unique.ptr.special] and other parts of the standard.
The result of this is that we give now implicit support for potentially throwing comparison functions, but <strong>not</strong>
for homogeneous <tt>==</tt> and <tt>!=</tt>, which might be a bit surprising.
</p>

<h2><a name="Akn"></a>Acknowledgements</h2>
<p>
The first author would like to express special thanks to Howard Hinnant and Alisdair Meredith for many detailed improvement
suggestions and reviews during several stages of this proposal and to Alberto Ganesh Barbati, Beman Dawes,
and Peter Dimov for valuable discussions and improvement suggestions.
The second author 
acknowledges the Fermi National Accelerator Laboratory's Computing Division for sponsoring his participation in the C++ standardization effort.

</p>
</body></html>
