Files
boost_range/doc/boost_range.html

487 lines
22 KiB
HTML
Raw Normal View History

2004-08-05 19:37:40 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Boost.Range Range Implementation </title>
<meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1">
2004-08-10 09:56:55 +00:00
<link rel="stylesheet" href="style.css" type="text/css">
2004-08-05 19:37:40 +00:00
</head>
2004-08-10 11:53:33 +00:00
<body>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<table >
<tr >
<td ><img src="cboost.gif" width="100%" border="0"></td>
<td ><h1 ><br>
Boost.Range </h1></td>
</tr>
</table>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<h2>Single Pass Range, Forward Range and Bidirectional Range Implementation</h2>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<ul >
<li>
<a href="#overview">Overview</a>
<li >
<a href="#Synopsis" >Synopsis</a>
</li>
<li >
<a href="#Semantics" >Semantics</a>
</li>
2004-08-12 10:58:13 +00:00
<li>
<a href="#minimal_interface">Extending the library</a>
2004-08-10 11:53:33 +00:00
</ul>
<hr size="1" >
2004-08-10 09:56:55 +00:00
2004-08-10 11:53:33 +00:00
<h3>Overview</h3>
<p>
Four types of objects are currently supported by the library:
<ul >
<li >
2004-08-12 10:58:13 +00:00
standard-like containers
2004-08-10 11:53:33 +00:00
</li>
<li >
<code >std::pair&lt;iterator,iterator&gt;</code>
</li>
<li >
null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,
<code >char*</code>, and <code >wchar_t*</code>)
</li>
<li >
built-in arrays
</li>
</ul>
2004-08-12 10:58:13 +00:00
Even though the behavior of the primary templates are exactly such that standard
containers will be supported by default, the requirements are much lower than
the standard container requirements. For example, the utility class <a
href="utility_class.html#iter_range"><code>iterator_range</code></a> implements
the <a href="#minimal_interface">minimal interface</a> required to make the
class a <a href="range.htm#forward_range">Forward Range</a>.
2004-08-10 11:53:33 +00:00
</p>
2004-08-12 10:58:13 +00:00
2004-08-10 11:53:33 +00:00
<p>
2004-08-12 10:58:13 +00:00
Please also see <a href="range.htm">Range concepts</a> for more details.
2004-08-10 11:53:33 +00:00
</p>
2004-08-12 10:58:13 +00:00
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
2004-08-10 09:56:55 +00:00
2004-08-10 11:53:33 +00:00
<p >
2004-08-10 09:56:55 +00:00
2004-08-10 11:53:33 +00:00
<pre>
2004-08-12 10:58:13 +00:00
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Single Pass Range metafunctions
2004-08-10 09:56:55 +00:00
//
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#value_type_of"><span
class=identifier>value_type_of</span></a><span class=special>;
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#iterator_of"><span
class=identifier>iterator_of</span></a><span class=special>;
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#const_iterator_of"><span
class=identifier>const_iterator_of</span></a><span class=special>;
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Forward Range metafunctions
//
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#difference_type_of"><span
class=identifier>difference_type_of</span></a><span class=special>;
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#size_type_of"><span
class=identifier>size_type_of</span></a><span class=special>;
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Bidirectional Range metafunctions
//
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a
href="#reverse_iterator_of"><span
class=identifier>reverse_iterator_of</span></a><span class=special>;
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a
href="#const_reverse_iterator_of"><span
class=identifier>const_reverse_iterator_of</span></a><span class=special>;
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Special metafunctions
//
2004-06-29 02:58:13 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#result_iterator_of"><span
class=identifier>result_iterator_of</span></a><span class=special>;
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a
href="#reverse_result_iterator_of"><span
class=identifier>reverse_result_iterator_of</span></a><span class=special>;
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Single Pass Range functions
2004-08-10 09:56:55 +00:00
//
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-06-29 02:58:13 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>bool
</span><a href="#empty"><span class=identifier>empty</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 09:56:55 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Forward Range functions
//
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>size_type_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#size"><span class=identifier>size</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=comment>//
2004-08-10 11:53:33 +00:00
// Bidirectional Range functions
//
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>reverse_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_reverse_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>reverse_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
2004-08-10 11:53:33 +00:00
2004-08-12 10:58:13 +00:00
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_reverse_iterator_of</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=keyword>const </span><span
class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span>
<span class=special>} </span><span class=comment>// namespace 'boost'
</span></pre>
2004-08-10 11:53:33 +00:00
</p>
2004-08-12 10:58:13 +00:00
<a name="Semantics" ></a> <h3 >Semantics</h3>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<h4>notation</h4>
<p>
<table cellpadding="5" border="1">
<tr>
<th>Type
<th>Object
<th>Describes
</tr>
<tr>
<td><code>X</code>
2004-08-12 10:58:13 +00:00
<td><code>x</code>
2004-08-10 11:53:33 +00:00
<td>any type
</tr>
<tr>
<td><code>T</code> </td>
<td><code>t</code>
<td>denotes behavior of the primary templates</td>
</tr>
<tr>
<td><code>P</code>
<td><code>p</code>
<td>denotes <code>std::pair&lt;iterator,iterator></code>
</tr>
<tr>
<td><code>A[sz]</code>
<td><code>a</code>
<td>denotes an array of type <code>A</code> of size <code>sz</code>
<tr>
<tr>
<td><code>Char*</code>
<td><code>s</code>
<td>denotes either <code>char*</code> or <code>wchar_t*</code>
</tr>
</table>
</p>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<p>
2004-08-12 10:58:13 +00:00
Please notice in tables below that when four lines appear in a cell, the first
line will describe the primary template, the second line pairs of iterators, the
third line arrays and the last line null-terminated strings.
2004-08-10 11:53:33 +00:00
</p>
<h4>Metafunctions</h4>
<p>
<table border="1" cellpadding="5" >
<tr >
<th >Expression</th>
<th >Return type</th>
<th >Complexity</th>
</tr>
<tr >
<a name="value_type_of" ></a>
<td ><code >value_type_of&lt;X&gt;::type</code></td>
<td ><code >T::value_type</code><br>
<code >boost::iterator_value&lt;P::first_type&gt;::type</code><br>
<code >A</code><br>
<code>Char</code>
<td >compile time</td>
</tr>
<tr >
<a name="iterator_of" ></a>
<td ><code >iterator_of&lt;X&gt;::type</code></td>
<td ><code >T::iterator</code><br>
2004-08-12 10:58:13 +00:00
<code >P::first_type</code><br>
<code >A*</code><br>
<code>Char*</code>
2004-08-10 11:53:33 +00:00
<td >compile time</td>
</tr>
<tr >
<a name="const_iterator_of" ></a>
<td ><code >const_iterator_of&lt;X&gt;::type</code></td>
<td ><code >T::const_iterator</code><br>
2004-08-12 10:58:13 +00:00
<code >P::first_type</code><br>
2004-08-10 11:53:33 +00:00
<code >const A*</code><br>
<code>const Char*</code>
<td >compile time</td>
</tr>
<tr >
<a name="difference_type_of" ></a>
<td ><code >difference_type_of&lt;X&gt;::type</code></td>
<td ><code >T::difference_type</code><br>
2004-08-12 10:58:13 +00:00
<code
2004-08-10 11:53:33 +00:00
>boost_iterator_difference&lt;P::first_type&gt;::type</code><br>
2004-08-12 10:58:13 +00:00
<code >std::ptrdiff_t</code><br>
<code >std::ptrdiff_t</code><br>
2004-08-10 11:53:33 +00:00
<td >compile time</td>
</tr>
<tr >
<a name="size_type_of" ></a>
<td ><code >size_type_of&lt;X&gt;::type</code></td>
<td ><code >T::size_type</code><br>
<code >std::size_t</code><br>
<code >std::size_t</code><br>
<code >std::size_t</code><br>
<td >compile time</td>
</tr>
2004-08-05 19:37:40 +00:00
<tr >
2004-08-10 11:53:33 +00:00
<a name="result_iterator_of" ></a>
<td ><code >result_iterator_of&lt;X&gt;::type</code></td>
2004-08-12 10:58:13 +00:00
<td ><code >const_iterator_of&lt;X&gt;::type</code> if <code
>X</code> is <code >const</code> <br>
2004-08-10 11:53:33 +00:00
<code >iterator_of&lt;X&gt;::type</code> otherwise </td>
<td >compile time</td>
</tr>
<tr >
<a name="reverse_iterator_of" ></a>
<td ><code >reverse_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename iterator_of&lt;T>::type ></code><br>
<td >compile time</td>
</tr>
<tr >
<a name="const_reverse_iterator_of" ></a>
<td ><code >const_reverse_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename const_iterator_of&lt;T>::type ></code>
<br>
<td >compile time</td>
</tr>
<tr >
<a name="reverse_result_iterator_of" ></a>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
2004-08-12 10:58:13 +00:00
<td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;::type
></code>
2004-08-10 11:53:33 +00:00
<td >compile time</td>
</tr>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
</table>
</p>
<p>
2004-08-12 10:58:13 +00:00
The special metafunctions <code>result_iterator_of</code> and <code>reverse_result_iterator_of</code>
are not part of any Range concept, but they are very useful when implementing
certain Range classes like <a
href="utility_class.html#sub_range"><code>sub_range</code></a> because of their
ability to select iterators based on constness.
2004-08-10 11:53:33 +00:00
</p>
<h4>Functions</h4>
<p>
<table border="1" cellpadding="5" >
<tr >
<th >Expression</th>
<th >Return type</th>
<th >Returns</th>
<th >Complexity</th>
</tr>
2004-08-05 19:37:40 +00:00
<tr >
2004-08-10 11:53:33 +00:00
<a name="begin" ></a>
<td ><code >begin(x)</code></td>
<td ><code >result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >t.begin()</code><br>
2004-08-12 10:58:13 +00:00
<code >p.first</code><br>
2004-08-10 11:53:33 +00:00
<code >a</code><br>
<code>s</code>
<td >constant time</td>
</tr>
<tr >
<a name="end" ></a>
<td ><code >end(x)</code></td>
<td ><code >result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >t.end()</code><br>
2004-08-12 10:58:13 +00:00
<code >p.second</code><br>
<code >a + sz</code> <br>
<code >s + std::char_traits&lt;X&gt;::length( s )</code> if <code >X</code> is <code >Char*</code>
<br>
2004-08-10 11:53:33 +00:00
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br>
2004-08-05 19:37:40 +00:00
2004-08-12 10:58:13 +00:00
2004-08-10 11:53:33 +00:00
<td >linear if <code >X</code> is <code >Char*</code> <br>
constant time otherwise</td>
</tr>
<tr >
<a name="empty" ></a>
<td ><code >empty(x)</code></td>
<td ><code >bool</code></td>
<td ><code >begin(x) == end( x )</code><br>
<td >linear if <code >X</code> is <code >Char*</code> <br>
constant time otherwise<br>
</td>
</tr>
<tr >
<a name="size" ></a>
<td ><code >size(x)</code></td>
<td ><code >size_type_of&lt;X&gt;::type</code></td>
<td ><code >t.size()</code><br>
2004-08-12 10:58:13 +00:00
<code>std::distance(p.first,p.second)</code><br>
<code >sz</code><br>
<code>end(s) - s</code>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
<td >linear if <code >X</code> is <code >Char*</code> <br>
or if <code >std::distance()</code> is linear <br>
constant time otherwise</td>
</tr>
<tr >
<a name="rbegin" ></a>
<td ><code >rbegin(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
2004-08-12 10:58:13 +00:00
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( end(x) )</code> <br>
<td >same as <code>end(x)</code> </td>
2004-08-10 11:53:33 +00:00
</tr>
<tr >
<a name="rend" ></a>
<td ><code >rend(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
2004-08-12 10:58:13 +00:00
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( begin(x) )</code>
<td >same as <code>begin(x)</code></td>
2004-08-10 11:53:33 +00:00
</tr>
2004-08-05 19:37:40 +00:00
2004-08-10 11:53:33 +00:00
</table>
</p>
2004-08-05 19:37:40 +00:00
<hr>
2004-08-12 10:58:13 +00:00
<a name=minimal_interface></a> <h3>Extending the library</h3>
<p>
The primary templates in this library are implemented such that standard
containers will work automatically and so will <code>boost::<a
href=../../array/index.html>array</a></code>. Below is given an overview of
which member functions and member types a class must specify to
be useable as a certain Range concept.
</p>
<p>
<table cellpadding="5" border="1">
<tr>
<th>Member function</th>
<th>Related concept</th>
<tr>
<td><code>begin()</code></td>
<td><a href="range.htm#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>end()</code> </td>
<td><a href="range.htm#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>size()</code></td>
<td><a href="range.htm#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p>
Notice that <code>rbegin()</code> and <code>rend()</code> member functions
are not needed even though the container can support bidirectional iteration.
</p>
<p>
The required member types are:
</p>
<p>
<table cellpadding="5" border="1">
<tr>
<th>Member type</th>
<th>Related concept</th>
<tr>
<tr>
<td><code>value_type</code></td>
<td><a href="range.htm#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>iterator</code></td>
<td><a href="range.htm#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>const_iterator</code></td>
<td><a href="range.htm#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>difference_type</code></td>
<td><a href="range.htm#forward_range">Forward Range</a></td>
</tr>
<tr>
<td><code>size_type</code></td>
<td><a href="range.htm#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p>
Again one should notice that member types <code>reverse_iterator</code> and
<code>const_reverse_iterator</code> are not needed.
</p>
<hr>
2004-08-05 19:37:40 +00:00
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>