<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2035: Output iterator requirements are broken</title>
<meta property="og:title" content="Issue 2035: Output iterator requirements are broken">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2035.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Open">Open</a> status.</em></p>
<h3 id="2035"><a href="lwg-active.html#2035">2035</a>. Output iterator requirements are broken</h3>
<p><b>Section:</b> 24.3.5.4 <a href="https://wg21.link/output.iterators">[output.iterators]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Daniel Kr&uuml;gler <b>Opened:</b> 2011-02-27 <b>Last modified:</b> 2025-03-13</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="lwg-index-open.html#output.iterators">active issues</a> in [output.iterators].</p>
<p><b>View all other</b> <a href="lwg-index.html#output.iterators">issues</a> in [output.iterators].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>During the Pittsburgh meeting the proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3066.html">N3066</a>
became accepted because it fixed several severe issues related to the iterator specification. But the current working draft (N3225)
does not reflect all these changes. Since I'm unaware whether every correction can be done editorial, this issue is submitted to take
care of that. To give one example: All expressions of Table 108 &mdash; &quot;Output iterator requirements&quot; have a post-condition
that the iterator is incrementable. This is impossible, because it would exclude any finite sequence that is accessed by an output 
iterator, such as a pointer to a C array. The N3066 wording changes did not have these effects.
</p>

<p><i>[2011-03-01: Daniel comments:]</i></p>


<p>This issue has some overlap with the issue <a href="lwg-active.html#2038" title="Missing definition for incrementable iterator (Status: Open)">2038</a><sup><a href="https://cplusplus.github.io/LWG/issue2038" title="Latest snapshot">(i)</a></sup> and I would prefer if we
could solve both at one location. I suggest the following approach:
</p>
<ol>
<li><p>The terms <code><i>dereferencable</i></code> and <code><i>incrementable</i></code> could be defined in a more
general way not restricted to iterators (similar to the concepts <code>HasDereference</code> and 
<code>HasPreincrement</code> from working draft N2914). But on the other hand, all current usages of 
<code><i>dereferencable</i></code> and <code><i>incrementable</i></code> are involved with types that satisfy 
iterator requirements. Thus, I believe that it is sufficient for C++0x to add corresponding definitions to 
24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a> and to let all previous usages of these terms refer to this 
sub-clause. Since the same problem occurs with the past-the-end iterator, this proposal suggest providing 
similar references to usages that precede its definition as well.
</p></li>
<li><p>We also need to ensure that all iterator expressions get either an operational semantics in
terms of others or we need to add missing pre- and post-conditions. E.g. we have the following
ones without semantics:
</p><blockquote><pre>
*r++ = o // output iterator
*r--     // bidirectional iterator
</pre></blockquote><p>
According to the <a href="https://www.boost.org/sgi/stl/OutputIterator.html">SGI specification</a>
these correspond to
</p><blockquote><pre>
{ *r = o; ++r; }                         // output iterator
{ reference tmp = *r; --r; return tmp; } // bidirectional iterator
</pre></blockquote><p>
respectively. Please note especially the latter expression for bidirectional iterator. It fixes a problem
that we have for forward iterator as well: Both these iterator categories provide stronger guarantees
than input iterator, because the result of the dereference operation is <code>reference</code>, and <strong>not</strong>
only convertible to the value type (The exact form from the SGI documentation does not correctly refer to
<code>reference</code>).
</p></li>
</ol>

<p><i>[2011-03-14: Daniel comments and updates the suggested wording]</i></p>


<p>In addition to the before mentioned necessary changes there is another one need, which
became obvious due to issue <a href="lwg-defects.html#2042" title="Comparing forward_list::before_begin() to forward_list::end() (Status: C++11)">2042</a><sup><a href="https://cplusplus.github.io/LWG/issue2042" title="Latest snapshot">(i)</a></sup>: <code>forward_list&lt;&gt;::before_begin()</code> returns
an iterator value which is not dereferencable, but obviously the intention is that it should
be incrementable. This leads to the conclusion that imposing dereferencable as a requirement
for the expressions <code>++r</code> is wrong: We only need the iterator to be incrementable. A
similar conclusion applies to the expression <code>--r</code> of bidirectional iterators.</p>

<p><i>[
2011 Bloomington
]</i></p>


<p>
Consensus this is the correct direction, but there are (potentially) missing <i>incrementable</i>
preconditions on some table rows, and the Remarks on when an output iterator becomes dereferencable
are probably better handled outside the table, in a manner similar to the way we word for input
iterators.
</p>

<p>
There was some concern about redundant pre-conditions when the operational semantic is defined in
terms of operations that have preconditions, and a similar level of concern over dropping such
redundancies vs. applying a consistent level of redundant specification in all the iterator tables.
Wording clean-up in either direction would be welcome.
</p>

<p><i>[2011-08-18: Daniel adapts the proposed resolution to honor the Bloomington request]</i></p>


<p>
There is only a small number of further changes suggested to get rid of superfluous 
requirements and essentially non-normative assertions. Operations should not have extra 
pre-conditions, if defined by "in-terms-of" semantics, see e.g. <code>a != b</code> or <code>a-&gt;m</code> 
for Table 107. Further, some remarks, that do not impose anything or say nothing new have been removed, 
because I could not find anything helpful they provide.
E.g. consider the remarks for Table 108 for the operations dereference-assignment and
preincrement: They don't provide additional information say nothing surprising. With the
new pre-conditions <em>and</em> post-conditions it is implied what the remarks intend to say.
</p>

<p><i>[
2011-11-03: Some observations from Alexander Stepanov via c++std-lib-31405
]</i></p>


<p>
The following sentence is dropped from the standard section on OutputIterators:
<p/>
"In particular, the following two conditions should hold: first, any
iterator value should be assigned through before it is incremented
(this is, for an output iterator <code>i, i++; i++;</code> is not a valid code
sequence); second, any value of an output iterator may have at most
one active copy at any given time (for example, <code>i = j; *++i = a; *j = b;</code> 
is not a valid code sequence)."
</p>

<p><i>[
2011-11-04: Daniel comments and improves the wording
]</i></p>


<p>
In regard to the first part of the comment, the intention of the newly proposed wording 
was to make clear that for the expression
</p>
<blockquote><pre>
*r = o
</pre></blockquote>
<p>
we have the precondition dereferenceable and the post-condition
incrementable. And for the expression
</p>
<blockquote><pre>
++r
</pre></blockquote>
<p>
we have the precondition incrementable and the post-condition dereferenceable 
or past-the-end. This <em>should not</em>  allow for a sequence like <code>i++; i++;</code> 
but I agree that it doesn't exactly say that.
<p/>
In regard to the second point: To make this point clearer, I suggest to
add a similar additional wording as we already have for input iterator to the 
"Assertion&#47;note" column of the expression <code>++r</code>:
<p/>
"Post: any copies of the previous value of <code>r</code> are no longer 
required to be dereferenceable or incrementable."
<p/>
The proposed has been updated to honor the observations of Alexander Stepanov.
</p>

<p><i>[2015-02 Cologne]</i></p>

<p>
The matter is complicated, Daniel volunteers to write a paper.
</p>



<p id="res-2035"><b>Proposed resolution:</b></p>
<ol>
<li><p>Add a reference to 24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a> to the following parts of the
library preceding Clause 24 Iterators library: (I stopped from 23.2.8 <a href="https://wg21.link/unord.req">[unord.req]</a> on, because
the remaining references are the concrete containers)</p>
<ol>
<li><p>16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a> p5:</p>

<blockquote><p>
-5- A type <code>X</code> satisfying any of the iterator requirements (24.2) is <code><i>ValueSwappable</i></code> if, 
for any dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> object <code>x</code> of type 
<code>X</code>, <code>*x</code> is swappable.
</p></blockquote>
</li>

<li><p>16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>, Table 27 &mdash; &quot;Descriptive variable definitions&quot;, 
row with the expression <code>c</code>:</p>

<blockquote><p>
a dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> pointer of type <code>C*</code>
</p></blockquote>

</li>

<li><p>20.2.3.3 <a href="https://wg21.link/pointer.traits.functions">[pointer.traits.functions]</a>:</p>
<blockquote><p>
<i>Returns</i>: The first template function returns a dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> 
pointer to <code>r</code> obtained by calling <code>Ptr::pointer_to(r)</code>;  [&hellip;]
</p></blockquote>
</li>

<li><p>27.4.3.4 <a href="https://wg21.link/string.iterators">[string.iterators]</a> p. 2:</p>
<blockquote><p>
<i>Returns</i>: An iterator which is the past-the-end value <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins>.
</p></blockquote>
</li>

<li><p>28.3.4.6.2.3 <a href="https://wg21.link/locale.time.get.virtuals">[locale.time.get.virtuals]</a> p. 11:</p>
<blockquote><pre>
iter_type do_get(iter_type s, iter_type end, ios_base&amp; f,
  ios_base::iostate&amp; err, tm *t, char format, char modifier) const;
</pre><blockquote><p>
<i>Requires</i>: <code>t</code> shall be dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins>.
</p></blockquote></blockquote>
</li>

<li><p>23.2.2 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> p. 6:</p>

<blockquote><p>
[&hellip;]  <code>end()</code> returns an iterator which is the past-the-end <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> 
value for the container.  [&hellip;]
</p></blockquote>
</li>

<li><p>23.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> p. 3:</p>

<blockquote><p>
[&hellip;]  <code>q</code> denotes a valid dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> 
const iterator to <code>a</code>,  [&hellip;]
</p></blockquote>
</li>

<li><p>23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a> p. 8 (I omit intentionally one further reference in the same sub-clause):</p>

<blockquote><p>
[&hellip;]  <code>q</code> denotes a valid dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> 
const iterator to <code>a</code>,  [&hellip;]
</p></blockquote>
</li>

<li><p>23.2.8 <a href="https://wg21.link/unord.req">[unord.req]</a> p. 10 (I omit intentionally one further reference in the same sub-clause):</p>

<blockquote><p>
[&hellip;]  <code>q</code> and <code>q1</code> are valid dereferenceable <ins>(24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a>)</ins> 
const iterators to <code>a</code>,  [&hellip;]
</p></blockquote>
</li>
</ol>

</li>
<li><p>Edit 24.3.1 <a href="https://wg21.link/iterator.requirements.general">[iterator.requirements.general]</a> p. 5 as indicated (The intent is to properly define
<i>incrementable</i> and to ensure some further library guarantee related to past-the-end iterator values):</p>

<blockquote><p>
-5- Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element
of the array, so for any iterator type there is an iterator value that points past the last element of a
corresponding sequence. These values are called <i>past-the-end values</i>. Values of an iterator <code>i</code> for which the
expression <code>*i</code> is defined are called <i>dereferenceable</i>. <ins>Values of an iterator <code>i</code> for which the
expression <code>++i</code> is defined are called <i>incrementable</i>. </ins> The library never assumes that 
past-the-end values are dereferenceable <ins>or incrementable</ins>. Iterators can also have singular values 
that are not associated with any sequence. [&hellip;]
</p></blockquote>
</li>

<li><p>Modify the column contents of Table 106 &mdash; &quot;Iterator requirements&quot;, 
24.3.5.2 <a href="https://wg21.link/iterator.iterators">[iterator.iterators]</a>, as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 106 &mdash; Iterator requirements</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td><code>*r</code></td>
<td><code>reference</code></td>
<td><code>&nbsp;</code></td>
<td>pre: <code>r</code> is dereferenceable.</td>
</tr>

<tr>
<td><code>++r</code></td>
<td><code>X&amp;</code></td>
<td><code>&nbsp;</code></td>
<td><ins>pre: <code>r</code> is incrementable.</ins></td>
</tr>

</table>
</blockquote>
</li>

<li><p>Modify the column contents of Table 107 &mdash; &quot;Input iterator requirements&quot;, 
24.3.5.3 <a href="https://wg21.link/input.iterators">[input.iterators]</a>, as indicated [<i>Rationale</i>: The wording changes attempt
to define a minimal "independent" set of operations, namely <code>*a</code> and <code>++r</code>, and 
to specify the semantics of the remaining ones. This approach seems to be in agreement with the 
original <a href="https://www.boost.org/sgi/stl/InputIterator.html">SGI specification</a>
&mdash; <i>end rationale</i>]:</p>

<blockquote>
<table border="1">
<caption>Table 107 &mdash; Input iterator requirements (in addition to Iterator)</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td><code>a != b</code></td>
<td>contextually<br/>
convertible to <code>bool</code></td>
<td><code>!(a == b)</code></td>
<td><del>pre: <code>(a, b)</code> is in the domain<br/>
of <code>==</code>.</del>
</td>
</tr>

<tr>
<td><code>*a</code></td>
<td>convertible to <code>T</code></td>
<td><code>&nbsp;</code></td>
<td>pre: <code>a</code> is dereferenceable.<br/>
The expression<br/>
<code>(void)*a, *a</code> is equivalent<br/>
to <code>*a</code>.<br/>
If <code>a == b</code> and <code>(a,b)</code> is in<br/>
the domain of <code>==</code> then <code>*a</code> is<br/>
equivalent to <code>*b</code>.
</td>
</tr>

<tr>
<td><code>a-&gt;m</code></td>
<td><code>&nbsp;</code></td>
<td><code>(*a).m</code></td>
<td><del>pre: <code>a</code> is dereferenceable.</del></td>
</tr>

<tr>
<td><code>++r</code></td>
<td><code>X&amp;</code></td>
<td><code>&nbsp;</code></td>
<td>pre: <code>r</code> is <del>dereferenceable</del><ins>incrementable</ins>.<br/>
post: <code>r</code> is dereferenceable or<br/>
<code>r</code> is past-the-end.<br/>
post: any copies of the<br/>
previous value of <code>r</code> are no<br/>
longer required either to be<br/>
dereferenceable<ins>, incrementable,</ins><br/>
or to be in the domain of <code>==</code>.
</td>
</tr>

<tr>
<td><code>(void)r++</code></td>
<td><code>&nbsp;</code></td>
<td><ins><code>(void)++r</code></ins></td>
<td><del>equivalent to <code>(void)++r</code></del></td>
</tr>

<tr>
<td><code>*r++</code></td>
<td>convertible to <code>T</code></td>
<td><code>{ T tmp = *r;<br/>
++r;<br/>
return tmp; }
</code></td>
<td><code>&nbsp;</code></td>
</tr>

</table>
</blockquote>
</li>

<li>
<p>Modify the column contents of Table 108 &mdash; &quot;Output iterator requirements&quot;, 
24.3.5.4 <a href="https://wg21.link/output.iterators">[output.iterators]</a>, as indicated [<i>Rationale</i>: The wording changes attempt
to define a minimal "independent" set of operations, namely <code>*r = o</code> and <code>++r</code>,
and to specify the semantics of the remaining ones. This approach seems to be in agreement with
the original <a href="https://www.boost.org/sgi/stl/OutputIterator.html">SGI specification</a>
&mdash; <i>end rationale</i>]:</p>

<blockquote>
<table border="1">
<caption>Table 108 &mdash; Output iterator requirements (in addition to Iterator)</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td><code>*r = o</code></td>
<td>result is not used</td>
<td><code>&nbsp;</code></td>
<td><ins>pre: <code>r</code> is dereferenceable.</ins><br/>
<i>Remark</i>: After this operation<br/>
<code>r</code> is not required to be<br/>
dereferenceable <ins>and any copies of<br/>
the previous value of <code>r</code> are no<br/>
longer required to be dereferenceable<br/>
or incrementable.</ins><br/>
post: <code>r</code> is incrementable.
</td>
</tr>

<tr>
<td><code>++r</code></td>
<td><code>X&amp;</code></td>
<td><code>&nbsp;</code></td>
<td><ins>pre: <code>r</code> is incrementable.</ins><br/>
<code>&amp;r == &amp;++r</code>.<br/>
<del><i>Remark</i>: After this operation<br/>
<code>r</code> is not required to be<br/>
dereferenceable.<br/></del>
<ins><i>Remark</i>: After this operation<br/>
<code>r</code> is not required to be<br/>
incrementable and any copies of<br/>
the previous value of <code>r</code> are no<br/>
longer required to be dereferenceable<br/>
or incrementable.</ins><br/>
post: <code>r</code> is <ins>dereferenceable<br/>
or <code>r</code> is past-the-end</ins><del>incrementable</del>.<br/>
</td>
</tr>

<tr>
<td><code>r++</code></td>
<td>convertible to <code>const X&amp;</code></td>
<td><code>{ X tmp = r;<br/>
  ++r;<br/>
  return tmp; }</code>
</td>
<td><del><i>Remark</i>: After this operation<br/>
<code>r</code> is not required to be<br/>
dereferenceable.<br/>
post: <code>r</code> is incrementable.</del>
</td>
</tr>

<tr>
<td><code>*r++ = o</code></td>
<td>result is not used</td>
<td><ins><code>{ *r = o; ++r; }</code></ins></td>
<td><del><i>Remark</i>: After this operation<br/>
<code>r</code> is not required to be<br/>
dereferenceable.<br/>
post: <code>r</code> is incrementable.</del>
</td>
</tr>
</table>
</blockquote>
</li>

<li><p>Modify the column contents of Table 109 &mdash; &quot;Forward iterator requirements&quot;, 
24.3.5.5 <a href="https://wg21.link/forward.iterators">[forward.iterators]</a>, as indicated [<i>Rationale</i>: Since the return type of the
expression <code>*r++</code> is now guaranteed to be type <code>reference</code>, the implied operational
semantics from input iterator based on value copies is wrong &mdash; <i>end rationale</i>]</p>

<blockquote>
<table border="1">
<caption>Table 109 &mdash; Forward iterator requirements (in addition to input iterator)</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td><code>r++</code></td>
<td>convertible to <code>const X&amp;</code></td>
<td><code>{ X tmp = r;<br/>
  ++r;<br/>
  return tmp; }</code>
</td>
<td><code>&nbsp;</code></td>
</tr>

<tr>
<td><code>*r++</code></td>
<td>reference</td>
<td><ins><code>{ reference tmp = *r;<br/>
 ++r;<br/> 
 return tmp; }</code></ins></td>
<td><code>&nbsp;</code></td>
</tr>
</table>
</blockquote>

</li>

<li><p>Modify the column contents of Table 110 &mdash; &quot;Bidirectional iterator requirements&quot;, 
24.3.5.6 <a href="https://wg21.link/bidirectional.iterators">[bidirectional.iterators]</a>, as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 110 &mdash; Bidirectional iterator requirements (in addition to forward iterator)</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion&#47;note<br/>pre-&#47;post-condition</th>
</tr>

<tr>
<td><code>--r</code></td>
<td><code>X&amp;</code></td>
<td><code>&nbsp;</code></td>
<td>pre: there exists <code>s</code> such that<br/>
<code>r == ++s</code>.<br/>
post: <code>r</code> is <del>dereferenceable</del><ins>incrementable</ins>.<br/>
<code>--(++r) == r</code>.<br/>
<code>--r == --s</code> implies <code>r == s</code>.<br/>
<code>&amp;r == &amp;--r</code>.
</td>
</tr>

<tr>
<td><code>r--</code></td>
<td>convertible to <code>const X&amp;</code></td>
<td><code>{ X tmp = r;<br/>
  --r;<br/>
  return tmp; }</code>
</td>
<td><code>&nbsp;</code></td>
</tr>

<tr>
<td><code>*r--</code></td>
<td>reference</td>
<td><ins><code>{ reference tmp = *r;<br/>
 --r;<br/> 
 return tmp; }</code></ins></td>
<td><code>&nbsp;</code></td>
</tr>
</table>
</blockquote>
</li>
</ol>





</body>
</html>
