<!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=windows-1252">

<title>Moving Swap Forward</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: N2958=09-0148<br>
<br>
<a href="mailto:daniel.kruegler@googlemail.com">Daniel Krgler</a><br>
2009-09-24
</address>
<hr>
<h1 style="text-align: center;">Moving Swap Forward</h1>
<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a>
  <ul>
	<li><a href="#Swap"><tt>Swap</tt></a></li>
	<li><a href="#Forward"><tt>Forward</tt></a></li>
	<li><a href="#Move"><tt>Move</tt></a></li>
	<li><a href="#Value"><tt>Value</tt></a></li>
  </ul>
</li>
<li><a href="#Motivation">Motivation</a></li>
<li><a href="#Proposed_resolution">Proposed resolution</a></li>
<li><a href="#Acknowledgements">Acknowledgements</a></li>
</ul>

<h2><a name="Introduction"></a>Introduction</h2>
<p>
The functions <tt>forward</tt>, <tt>move</tt>, and <tt>swap</tt> are rather 
fundamental cornerstones which are near to language facilities instead of library 
features:
</p>
<h4><a name="Swap"></a><tt>Swap</tt></h4>
<p>
The <tt>swap</tt> function is an old friend from C++03, and became recently extended to be
applicable to native arrays with still some room for even more generality
(see e.g. issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#742">742</a>) 
for C++0x. The species <tt>swap</tt> can often be found in the neighbourhood
of move-semantics, e.g. a typical move assignment operator can be defined this way:
</p>
<blockquote><pre>
  Moveable&amp; Moveable::operator=(Moveable&amp;&amp; rhs) 
  {
    using std::swap;
    swap(member1, rhs.member1);
    swap(member2, rhs.member2);
    return *this;
  }
</pre></blockquote>
<p>
So <tt>swap</tt> has the very fundamental role of exchanging two things which is 
intimately related to the basics of copying and moving.
</p>
<h4><a name="Forward"></a><tt>Forward</tt></h4>
<p>
Due to the powerful <em>perfect forwarding</em> idiom, which was one of the most
important reasons for the introduction of rvalue-references, the <tt>forward</tt> 
function is needed to transfer the exact argument lvalueness information to the 
next layer with the following characteristic pattern:
</p>
<blockquote><pre>
  template&lt;class T&gt;
  void foo(T&amp;&amp; arg) 
  {
    bar(std::forward&lt;T&gt;(arg));
  }
</pre></blockquote>
<h4><a name="Move"></a><tt>Move</tt></h4>
<p>
Another important use-case for rvalue-references is the enablement of <em>move-semantic</em>
in C++. Rvalues can immediately be moved, but a similar need often exists for moving lvalues,
if they are no longer needed. For type-safety reasons those need an explicit cast 
to a corresponding rvalue-reference and that is what <tt>move</tt> has to realize:
</p>
<blockquote><pre>
  void sink(std::string&amp;&amp;);

  int main() 
  {
    std::string s = ...;
    ... // Do something with s
    sink(std::move(s)); // Transform s into an rvalue and let it move away
  }
</pre></blockquote>
<h4><a name="Value"></a><tt>Value</tt></h4>
<p>
With the provision of <tt>decltype</tt>, <em>late-specified return types</em>, and 
default template-arguments for function templates a new generation of <em>SFINAE</em> 
patterns will emerge to at least partially compensate the lack of concepts on the 
C++0x timescale. Using this technique, it is sometimes necessary to obtain an 
object of a known type in a non-using context, e.g.
</p>
<blockquote><pre>
  template&lt;class T&gt;
  T&amp;&amp; value(); // not used, therefore not defined
	
  template&lt;class To, class From&gt;
  auto convert(From&amp;&amp;) -&gt; decltype(static_cast&lt;To&gt;(value&lt;From&gt;()));
</pre></blockquote>
<p>
The role of the undefined function template <tt>value()</tt> is therefore a transformation
of a type <tt>T</tt> into a value without <em>using</em> or <em>evaluating</em> this function. 
The name is supposed to direct the reader's attention to the fact that the expression 
<tt>value&lt;T&gt;()</tt> is an <em>lvalue</em> if and only if <tt>T</tt> is an lvalue-reference, 
otherwise an <em>rvalue</em>. To extend the domain of this function we can do a bit better by 
changing it's declaration to
</p>
<blockquote><pre>
  template&lt;class T&gt;
  typename std::add_rvalue_reference&lt;T&gt;::type value(); // not used, therefore not defined
</pre></blockquote>
<p>
which ensures that we can also use <em>cv</em> <tt>void</tt> as template parameter. The careful reader 
might have noticed that <tt>value()</tt> already exists under the name <tt>create()</tt> as part 
of the definition of the semantic of the type trait <tt>is_convertible</tt> in [meta.rel]/4.
</p>
<p>
All four presented functions are extremely light-weight, but it is expected that they will be 
part of the daily tool-box of the C++0x programmer.
</p>

<h2><a name="Motivation"></a>Motivation</h2>
<p>
The three existing functions are located in the two headers <tt>&lt;utility&gt;</tt>
and <tt>&lt;algorithm&gt;</tt>, which are both quite huge. This means that using
these extremely fundamental functions always introduces a large overhead of code.
</p><p>
This negative aspect has lead to the national body comment 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2939.html#UK300"><b>UK 300</b></a> 
and this paper attempts to provide a solution for that, including an addition of a facility which
according to the author's assumptions is of similar fundamentability and usefulness
in template code.
</p><p>
The basic approach suggested in this paper is
</p><ul>
<li>
to move the current definitions of <tt>forward</tt>, <tt>move</tt>, and <tt>swap</tt> to 
a new small header in a backward-compatible manner;
</li>
<li>
to provide a new facility <tt>value()</tt> useful in the definition of constrained or
auto-deduced templates;
</li>
</ul>
<p>
Several naming suggestions for the header had been thought of - among these were <tt>&lt;transfer&gt;</tt> 
and <tt>&lt;moving&gt;</tt> - the currently proposed name is simply <b><tt>&lt;move&gt;</tt></b> 
following one prominent tradition of the standard headers to name the header equal 
to the name of one of it's components.
<p>
Similarly, several naming alternatives for <tt>value</tt> were also considered, e.g. <tt>decl</tt>
(suggested by Alisdair Meredith), <tt>create</tt>, <tt>make</tt>, or <tt>fwd</tt>. The name 
<b><tt>value</tt></b> has the advantage of not causing a confusion with already existing names 
(<tt>forward</tt>, <tt>decltype</tt>), it also emphasizes better it's actual intention - the
effect of attempting to get an <em>rvalue</em> or an <em>lvalue</em> - over <tt>make</tt> or <tt>create</tt>.
<p>
Several mechanisms were considered to ensure that an unguarded programmer cannot too easily misuse
the <em>undefined</em> function <tt>value</tt>. It is impossible to mark it as an <em>deleted</em>
function, because that would produce unwanted compile-time errors or silent removals from the
overload set, depending on the context of it's occurrence. It was considered to mark the function
with the attribute <tt>[[noreturn]]</tt>, but the author has the suspicion that this might 
produce unwanted warnings of compilers or other diagnostic tools also for the <em>intended</em> 
use-cases and still wouldn't prevent using it. A third option was thought of, namely to provide 
indeed a <em>definition</em> which would either cause termination or the raise of an exception. 
This idea was rejected, because such a misuse might reveal too late in the software development 
process. In the end it seemed the best compromise to simply provide no definition at all
and to rely on linker diagnostics to make any abuse obvious. On the positive side such scenarios 
seem less likely compared to an imprudent usage of another undefined function that would need 
<em>no</em> explicit template parameter for a valid call expression.
<p>
The proposed wording attempts to prevent direct coupling to other components by using
words that explain effects and semantics instead of code, e.g. the <tt>swap</tt> overload for 
arrays should have the same effect as a call to <tt>swap_ranges</tt>, but that should not imply
that <tt>&lt;algorithm&gt;</tt> should be included as well. Similarly should the declaration
of <tt>value()</tt> not imply the inclusion of the complete <tt>&lt;type_traits&gt;</tt>
header just because it's semantic depends on the semantic of <tt>add_rvalue_reference</tt>.
To prevent existing libraries to perform heroic efforts to satisfy this intention, the
wording uses no binding request, but instead a non-normative, encouraging wording style.

</p><h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The following suggested wording bases on the numbering of 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf">N2723</a>.
</p><p>
[<i>The following wording assumes that <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html">N2951</a> 
	has been applied. This proposal does not depend on the suggested resolution of N2951, but it simplifies the wording here.
  If N2951 would be rejected, this wording need only an update that ensures that the equivalent semantic effect of identity 
  is realized</i>]
</p><p>
</p><ol>
<li>
Add one further entry to Table 30 - General utilities library summary ([utilities])
immediately before <tt>&lt;utility&gt;</tt>:
<p>

</p><blockquote>
<table border="1">
<caption>Table 30  General utilities library summary</caption>

<tbody><tr>
<th>Subclause</th>
<th>Header(s)</th>
</tr>

<tr>
<td>20.1&#8195;Requirements</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><ins>20.2&#8195;Move and forward functions</ins></td>
<td><ins><tt>&lt;move&gt;</tt></ins></td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>

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

<p>

</p></li><li>Change [utilities.general]/2:
<blockquote>
<p>
The following subclauses describe utility and allocator requirements, <ins>move/forward utilities,</ins> 
utility components, compile-time rational arithmetic, tuples, type traits templates, function objects, 
dynamic memory management utilities, and date/time utilities, as summarized in Table 30.
</p></blockquote>
</li>
<li>Add a new clause just before [utility]:
<blockquote>
<p>
<ins>20.2    Move and forward functions    [move.forward]</ins>
</p><p>
<ins>This subclause describes components used by C++ programs, particularly in templates,
to perform fundamental operations related to moving, forwarding, and swapping objects.</ins>
</p><p>
<ins><b>Header <tt>&lt;move&gt;</tt> synopsis</b></ins>
</p><p>
</p><blockquote><pre><ins>namespace std {</ins>

  <ins>// 20.2.1, forward/move:</ins>
  <ins>template &lt;class T, class U&gt; T&amp;&amp; forward(U&amp;&amp; u);</ins>
  <ins>template &lt;class T&gt; <i>MT</i> move(T&amp;&amp;);</ins>

  <ins>// 20.2.2, value:</ins>
  <ins>template &lt;class T&gt; <i>VT</i> value(); // intentionally undefined</ins>

  <ins>// 20.2.3, swap:</ins>
  <ins>template &lt;class T&gt; void swap(T&amp; a, T&amp; b);</ins>
  <ins>template &lt;class T, size_t N&gt; void swap(T (&amp;a)[N], T (&amp;b)[N]);</ins>

<ins>}</ins>
</pre></blockquote>
<p>
<ins><b>20.2.1 forward/move helpers [forward]</b></ins>
</p><p>
<ins>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>
<p>
[<i>NB: The following is a relocation of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html">N2951</a>
wording from [forward] around p. 3. Additionally a Notes clause is added to signal implementors that they should not include 
the header <tt>&lt;type_traits&gt;</tt> here:</i>]
</p><p>
</p><blockquote><pre><ins>template &lt;class T, class U&gt; T&amp;&amp; forward(U&amp;&amp; u);</ins>
</pre>
<p></p><blockquote>
<ins><i>Returns:</i> <tt>static_cast&lt;T&amp;&amp;&gt;(u)</tt>.</ins>
<p>
<ins><i>Remarks:</i> If the following constraints are not met, this signature shall not participate in overload resolution:</ins>
</p><ul><li>
<ins>The type formed by <tt>remove_reference&lt;U&gt;::type*</tt> shall be implicitly convertible to the type <tt>remove_reference&lt;T&gt;::type*</tt>, and</ins> 
</li>
<li>
<ins>if <tt>T</tt> is an lvalue reference type, then <tt>U</tt> shall be an lvalue reference type.</ins>
</li>
</ul>
<p>
<ins><i>Notes:</i> Implementations are encouraged but not required to avoid including the header 
	<tt>&lt;type_traits&gt;</tt> to realize this definition.</ins>
</p><p>
</p></blockquote></blockquote>

<p>
[<i>NB: The following is an unconditional relocation of the example from [forward]/5:</i>]
</p><blockquote><blockquote>
<ins>[<i>Example:</i></ins><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(std::forward&lt;A1&gt;(a1), std::forward&lt;A2&gt;(a2)));
}

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

void g() {
  shared_ptr&lt;A&gt; sp1 = factory&lt;A&gt;(2, 1.414); // error: 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><ins>
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A's constructor as an
rvalue. In the second call to factory, A1 is deduced as int&amp;, so i is forwarded to A's constructor as
an lvalue. In both cases, A2 is deduced as double, so 1.414 is forwarded to A's constructor
as an rvalue.  <i>end example</i>]</ins>
</blockquote>

</blockquote>
[<i>NB: The following is a relocation of <tt>move</tt> from [forward]/7-9 with one further
change: The introduction of <tt>MT</tt> is supposed to signal implementors that they
should not include the header <tt>&lt;type_traits&gt;</tt> here:</i>]
<blockquote>
	
<pre><ins>
template &lt;class T&gt; <i>MT</i> move(T&amp;&amp; t);
</ins></pre>

<blockquote>
<ins><i>Requires:</i> The return type <i><tt>MT</tt></i> shall be defined equivalent to 
<tt>typename remove_reference&lt;T&gt;::type&amp;&amp;</tt>.</ins>
<p>
<ins><i>Returns:</i> <tt>t</tt>.</ins>
</p><p>
<ins><i>Notes:</i> Implementations are encouraged but not required to avoid including the header 
<tt>&lt;type_traits&gt;</tt> to realize the definition of <i><tt>MT</tt></i>.</ins>
</p><p>
<ins>[<i>Example</i>:</ins></p><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(std::forward&lt;A1&gt;(a1)));
}

struct A {
  A();
  A(const A&amp;); // copies from lvalues
  A(A&amp;&amp;); // moves from rvalues
};

void g() {
  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; sp1 = factory&lt;A&gt;(std::move(a)); // "a" binds to A(A&amp;&amp;)
}
</ins></pre><ins>
- In the first call to factory, A1 is deduced as A&amp;, so a is forwarded as a non-const lvalue. This binds to
the constructor A(const A&amp;), which copies the value from a. In the second call to factory, because of
the call std::move(a), A1 is deduced as A, so a is forwarded as an rvalue. This binds to the constructor
A(A&amp;&amp;), which moves the value from a.  <i>end example</i>]</ins>
</blockquote>

</blockquote>
[<i>NB: Here starts the wording for the new library component <tt>value</tt>. The introduction of 
<tt>VT</tt> is supposed to signal implementors that they should not include the header 
<tt>&lt;type_traits&gt;</tt> here:</i>]
<blockquote>

<ins><b>20.2.2 Function template <tt>value</tt> [value]</b></ins>
<p>
<ins>The library provides the declaration but no definition for the function template <tt>value</tt> to simplify
the definition of types via expressions in unevaluated and unused contexts ([basic.def.odr], [expr]). The 
template parameter <tt>T</tt> of <tt>value</tt> may be an incomplete type.</ins>

</p><pre><ins>
template &lt;class T&gt; <i>VT</i> value(); // intentionally undefined
</ins></pre>

<blockquote>
<ins><i>Requires:</i> The return type <i><tt>VT</tt></i> shall be defined equivalent to 
<tt>typename add_rvalue_reference&lt;T&gt;::type</tt>.</ins>
<p>
<ins><i>Remarks:</i> The behavior is undefined, if the function is <em>used</em> according to [basic.def.odr].</ins>
<p>
<ins><i>Notes:</i> Implementations are encouraged but not required to avoid including the header 
	<tt>&lt;type_traits&gt;</tt> to realize the definition of <i><tt>VT</tt></i>.</ins>
</p><p>
<ins>[<i>Example</i>:</ins></p><blockquote><pre><ins>
template&lt;class To, class From&gt;
decltype(static_cast&lt;To&gt;(value&lt;From&gt;())) convert(From&amp;&amp;);
</ins></pre></blockquote>
<p><ins>
declares a function template <tt>convert</tt>, which does only participate in overloading, if the type
<tt>From</tt> can be explicitly casted to type <tt>To</tt>  <i>end example</i>]</ins>
</p></blockquote>

</blockquote>
[<i>NB: The following is a relocation of <tt>swap</tt> from [algorithms] with two further
changes: First, the clause is named [swap] instead of [algo.swap], because the latter is supposed to
be conserved for it's other components. Second, the semantic definition of the overload for arrays uses 
wording to encourage implementors not to include header <tt>&lt;algorithm&gt;</tt> here. Except for this
no change in semantic is intended but the introduction of the normative "equivalent to" 
phrase seems to fix a current wording impreciseness.</i>]
<blockquote>

<ins><b>20.2.3 <tt>Swap</tt> function templates [swap]</b></ins>
<pre><ins>
template&lt;class T&gt;
void swap(T&amp; a, T&amp; b);
</ins></pre>
<p>
<ins><i>Requires:</i> Type <tt>T</tt> shall be <tt>MoveConstructible</tt> (33) and <tt>MoveAssignable</tt> (35).</ins>	
</p><p>
<ins><i>Effects:</i> Exchanges values stored in two locations.</ins>

</p><pre><ins>
template&lt;class T, size_t N&gt;
void swap(T (&amp;a)[N], T (&amp;b)[N]);	
</ins></pre>
<p>
<ins><i>Effects:</i> Equivalent to <tt>swap_ranges(a, a + N, b)</tt>.</ins>
</p><p>
<ins><i>Notes:</i> Implementations are encouraged but not required to avoid including the header <tt>&lt;algorithm&gt;</tt> 
to realize the definition of this <tt>swap</tt> overload.</ins>

</p></blockquote>
</li>
<li>Change [utilities] as indicated:
<p>
[<i>NB: The explicit addition of &lt;move&gt; ensures backward compatibility versus TR1</i>]
</p><blockquote>
<p>
<b>Header <tt>&lt;utility&gt;</tt> synopsis</b>
</p><p>
</p><blockquote><pre>#include &lt;initializer_list&gt;
<ins>#include &lt;move&gt;</ins>

namespace std {
  ...
  <del>// 20.3.2, forward/move:</del>
  <del>template &lt;class T&gt; struct identity;</del>
  <del>template &lt;class T&gt; T&amp;&amp; forward(typename identity&lt;T&gt;::type&amp;&amp;);</del>
  <del>template &lt;class T&gt; typename remove_reference&lt;T&gt;::type&amp;&amp; move(T&amp;&amp;);</del>
  ...
}
</pre></blockquote></blockquote>
</li>
<li>
Remove the complete clause 20.2.2 [forward].
<p>

</p></li><li>Change [meta.rel]/4 as indicated:
<p>
[<i>NB: This wording change is just an editorial simplification of the definition of
<tt>is_convertible</tt>. No wording change is intended, but we use already the wording
that was introduced with LWG defect <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#975">975</a></i>]
</p><p>
...
<del>Given the following function prototype:</del>
</p><blockquote><pre><del>
template &lt;class T&gt; 
typename add_rvalue_reference&lt;T&gt;::type create();
</del></pre></blockquote>
<del>t</del><ins>T</ins>he predicate condition for a template specialization <tt>is_convertible&lt;From, To&gt;</tt> 
shall be satisfied, if and only if the return expression in the following code would be well-formed, including 
any implicit conversions to the return type of the function.
<blockquote><pre>To test() { 
  return <del>create</del><ins>value</ins>&lt;From&gt;(); 
}
</pre></blockquote>
[<i>Note:</i> This requirement gives well defined results for reference types, <tt>void</tt> types, array types, 
	and function types.  <i>end note</i>]
<p>

</p></li><li>Change [meta.trans.other]/3 as indicated:
<p>
[<i>NB: This wording change is more than an editorial simplification of the definition of
<tt>common_type</tt>: It also extends it's usefulness for the rare but possible situation of a
cv <tt>void</tt> =&gt; cv <tt>void</tt> transformation and thus makes e.g. <tt>common_type</tt> usable
for all binary type combinations that are supported by <tt>is_convertible</tt></i>]
</p><p>
The nested typedef <tt>common_type::type</tt> shall be defined as follows:
</p>
<blockquote><pre>...
template &lt;class T, class U&gt;
struct common_type&lt;T, U&gt; {
<del>private:
  static T&amp;&amp; __t();
  static U&amp;&amp; __u();
public:</del>
  typedef decltype(true ? <del>__t</del><ins>value&lt;T&gt;</ins>() : <del>__u</del><ins>value&lt;U&gt;</ins>()) type;
};
...
</pre></blockquote>
</li>
<li>Change 25 [algorithms], header <tt>&lt;algorithm&gt;</tt> as indicated:
<p>
[<i>NB: The explicit addition of &lt;move&gt; ensures backward compatibility versus C++03</i>]
</p><p>
<b>Header <tt>&lt;algorithm&gt;</tt> synopsis</b>
</p><blockquote><pre><ins>#include &lt;move&gt;</ins>

namespace std {
  ...
  // 25.2.3, swap:
  <del>template&lt;class T&gt; void swap(T&amp; a, T&amp; b);</del>
  <del>template&lt;class T, size_t N&gt; void swap(T (&amp;a)[N], T (&amp;b)[N]);</del>
  template&lt;class ForwardIterator1, class ForwardIterator2&gt;
  ForwardIterator2 swap_ranges(ForwardIterator1 first1,
  ForwardIterator1 last1, ForwardIterator2 first2);
  template&lt;class ForwardIterator1, class ForwardIterator2&gt;
  void iter_swap(ForwardIterator1 a, ForwardIterator2 b);
  ...
 }
</pre></blockquote>
</li>
<li>Change 25.2.3 [alg.swap] as indicated:
<p>
</p><pre><del>
template&lt;class T&gt;
void swap(T&amp; a, T&amp; b);
</del></pre>
<p>
<del><i>Requires:</i> Type <tt>T</tt> shall be <tt>MoveConstructible</tt> (33) and <tt>MoveAssignable</tt> (35).</del>	
</p><p>
<del><i>Effects:</i> Exchanges values stored in two locations.</del>

</p><pre><del>
template&lt;class T, size_t N&gt;
void swap(T (&amp;a)[N], T (&amp;b)[N]);	
</del></pre>
<p>
<del><i>Effects:</i> <tt>swap_ranges(a, a + N, b)</tt>.</del>

</p></li></ol>
	
<h2><a name="Acknowledgements"></a>Acknowledgements</h2>
<p>
The author would like to thank Alisdair Meredith for his encouragement to write this paper
and for his inspiration to add the <tt>value</tt> function.
</p><p>
I would also like to acknowledge Howard Hinnant's careful suggestions which really helped improving this document.
</p><p>
</p>
</body></html>