added discussion on extension mechanism

[SVN r30854]
This commit is contained in:
Thorsten Jørgen Ottosen
2005-09-07 16:12:03 +00:00
parent 43a83f500e
commit 06e624858b
3 changed files with 747 additions and 402 deletions

View File

@ -1,78 +1,67 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <html>
<head> <head>
<title>Boost.Range Range Implementation </title> <title>Boost.Range Range Implementation </title>
<meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="style.css" type="text/css"> <link rel="stylesheet" href="style.css" type="text/css">
</head> </head>
<body> <body>
<table>
<table > <tr>
<tr > <td><img src="../../../boost.png" width="100%" border="0"></td>
<td ><img src="../../../boost.png" width="100%" border="0"></td> <td><h1><br>
<td ><h1 ><br> Boost.Range
Boost.Range </h1></td> </h1>
</td>
</tr> </tr>
</table> </table>
<h2>Synopsis and Reference
<h2>Synopsis and Reference </h2> </h2>
<ul>
<ul >
<li> <li>
<a href="#overview">Overview</a> <a href="#overview">Overview</a>
<li >
<a href="#Synopsis" >Synopsis</a>
</li>
<li >
<a href="#Semantics" >Semantics</a>
</li>
<li> <li>
<a href="#minimal_interface">Extending the library</a> <a href="#Synopsis">Synopsis</a>
<li>
<a href="#Semantics">Semantics</a>
<li>
<a href="#minimal_interface">Extending the library</a></li>
</ul> </ul>
<hr size="1" > <hr size="1">
<a name="overview"></a> <a name="overview"></a>
<h3>Overview</h3> <h3>Overview</h3>
<p> <p>
Four types of objects are currently supported by the library: Four types of objects are currently supported by the library:
<ul > <ul>
<li > <li>
standard-like containers standard-like containers
</li> <li>
<li > <code>std::pair&lt;iterator,iterator&gt;</code>
<code >std::pair&lt;iterator,iterator&gt;</code> <li>
</li> null terminated strings (this includes <code>char[]</code>,<code>wchar_t[]</code>,
<li > <code>char*</code>, and <code>wchar_t*</code>)
null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,
<code >char*</code>, and <code >wchar_t*</code>)
<p> <p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will <b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i> disappear in the next Boost release (1.34). </i>
</p> </p>
<li>
</li>
<li >
built-in arrays built-in arrays
</li> </li>
</ul> </ul>
Even though the behavior of the primary templates are exactly such that
Even though the behavior of the primary templates are exactly such that standard standard containers will be supported by default, the requirements are much
containers will be supported by default, the requirements are much lower than lower than the standard container requirements. For example, the utility class <a href="utility_class.html#iter_range">
the standard container requirements. For example, the utility class <a <code>iterator_range</code></a> implements the <a href="#minimal_interface">minimal
href="utility_class.html#iter_range"><code>iterator_range</code></a> implements interface</a> required to make the class a <a href="range.html#forward_range">Forward
the <a href="#minimal_interface">minimal interface</a> required to make the Range</a>
class a <a href="range.html#forward_range">Forward Range</a>. .
</p> <P></P>
<p> <p>
Please also see <a href="range.html">Range concepts</a> for more details. Please also see <a href="range.html">Range concepts</a> for more details.
</p> </p>
<a name="Synopsis"></a>
<a name="Synopsis" ></a> <h3 >Synopsis</h3> <h3>Synopsis</h3>
<p>
<p >
<pre> <pre>
<span class=keyword>namespace </span><span class=identifier>boost</span> <span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{ <span class=special>{
@ -207,33 +196,34 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<span class=special>} </span><span class=comment>// namespace 'boost' <span class=special>} </span><span class=comment>// namespace 'boost'
</span> </span>
</pre> </pre>
</p> <P></P>
<a name="Semantics"></a>
<a name="Semantics" ></a> <h3 >Semantics</h3> <h3>Semantics</h3>
<h4>notation</h4> <h4>notation</h4>
<p> <p>
<table cellpadding="5" border="1"> <table cellpadding="5" border="1">
<tr> <tr>
<th>Type <th>
<th>Object Type
<th>Describes <th>
Object
<th>
Describes
</tr> </tr>
<tr> <tr>
<td><code>X</code> <td><code>X</code>
<td><code>x</code> <td><code>x</code>
<td>any type <td>any type</td>
</tr>
<tr> <tr>
<td><code>T</code> </td> <td><code>T</code>
</td>
<td><code>t</code> <td><code>t</code>
<td>denotes behavior of the primary templates</td> <td>denotes behavior of the primary templates</td>
</tr> </tr>
<tr> <tr>
<td><code>P</code> <td><code>P</code>
<td><code>p</code> <td><code>p</code>
<td>denotes <code>std::pair&lt;iterator,iterator></code> <td>denotes <code>std::pair&lt;iterator,iterator&gt;</code></td>
</tr>
<tr> <tr>
<td><code>A[sz]</code> <td><code>A[sz]</code>
<td><code>a</code> <td><code>a</code>
@ -242,250 +232,275 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<tr> <tr>
<td><code>Char*</code> <td><code>Char*</code>
<td><code>s</code> <td><code>s</code>
<td>denotes either <code>char*</code> or <code>wchar_t*</code> <td>denotes either <code>char*</code> or <code>wchar_t*</code></td>
</tr> </tr>
</table> </table>
</p> </p>
<p> <p>
Please notice in tables below that when four lines appear in a cell, the first 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 line will describe the primary template, the second line pairs of iterators,
third line arrays and the last line null-terminated strings. the third line arrays and the last line null-terminated strings.
</p> </p>
<h4>Metafunctions</h4> <h4>Metafunctions</h4>
<p> <p>
<table border="1" cellpadding="5" > <table border="1" cellpadding="5">
<tr > <tr>
<th >Expression</th> <th>
<th >Return type</th> Expression</th>
<th >Complexity</th> <th>
Return type</th>
<th>
Complexity</th>
</tr> </tr>
<tr > <tr>
<a name="range_value" ></a> <a name="range_value"></a>
<td ><code >range_value&lt;X&gt;::type</code></td> <td><code>range_value&lt;X&gt;::type</code></td>
<td ><code >T::value_type</code><br> <td><code>T::value_type</code><br>
<code >boost::iterator_value&lt;P::first_type&gt;::type</code><br> <code>boost::iterator_value&lt;P::first_type&gt;::type</code><br>
<code >A</code><br> <code>A</code><br>
<code>Char</code> <code>Char</code>
<td >compile time</td> <td>compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_iterator" ></a> <a name="range_iterator"></a>
<td ><code >range_iterator&lt;X&gt;::type</code></td> <td><code>range_iterator&lt;X&gt;::type</code></td>
<td ><code >T::iterator</code><br> <td><code>T::iterator</code><br>
<code >P::first_type</code><br> <code>P::first_type</code><br>
<code >A*</code><br> <code>A*</code><br>
<code>Char*</code> <code>Char*</code>
<td >compile time</td> <td>compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_const_iterator" ></a> <a name="range_const_iterator"></a>
<td ><code >range_const_iterator&lt;X&gt;::type</code></td> <td><code>range_const_iterator&lt;X&gt;::type</code></td>
<td ><code >T::const_iterator</code><br> <td><code>T::const_iterator</code><br>
<code >P::first_type</code><br> <code>P::first_type</code><br>
<code >const A*</code><br> <code>const A*</code><br>
<code>const Char*</code> <code>const Char*</code>
<td >compile time</td> <td>compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_difference" ></a> <a name="range_difference"></a>
<td ><code >range_difference&lt;X&gt;::type</code></td> <td><code>range_difference&lt;X&gt;::type</code></td>
<td ><code >T::difference_type</code><br> <td><code>T::difference_type</code><br>
<code <code>boost::iterator_difference&lt;P::first_type&gt;::type</code><br>
>boost::iterator_difference&lt;P::first_type&gt;::type</code><br> <code>std::ptrdiff_t</code><br>
<code >std::ptrdiff_t</code><br> <code>std::ptrdiff_t</code><br>
<code >std::ptrdiff_t</code><br> <td>compile time</td>
<td >compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_size" ></a> <a name="range_size"></a>
<td ><code >range_size&lt;X&gt;::type</code></td> <td><code>range_size&lt;X&gt;::type</code></td>
<td ><code >T::size_type</code><br> <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> <code>std::size_t</code><br>
<code >std::size_t</code><br> <code>std::size_t</code><br>
<td >compile time</td> <td>compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_result_iterator" ></a> <a name="range_result_iterator"></a>
<td ><code >range_result_iterator&lt;X&gt;::type</code></td> <td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type</code> if <code <td><code>range_const_iterator&lt;X&gt;::type</code> if <code>X</code> is <code>const</code>
>X</code> is <code >const</code> <br>
<code >range_iterator&lt;X&gt;::type</code> otherwise </td>
<td >compile time</td>
</tr>
<tr >
<a name="range_reverse_iterator" ></a>
<td ><code >range_reverse_iterator&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename range_iterator&lt;T>::type ></code><br>
<td >compile time</td>
</tr>
<tr >
<a name="range_const_reverse_iterator" ></a>
<td ><code >range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename range_const_iterator&lt;T>::type ></code>
<br> <br>
<td >compile time</td> <code>range_iterator&lt;X&gt;::type</code> otherwise
</td>
<td>compile time</td>
</tr> </tr>
<tr > <tr>
<a name="range_reverse_result_iterator" ></a> <a name="range_reverse_iterator"></a>
<td ><code >range_reverse_result_iterator&lt;X&gt;::type</code></td> <td><code>range_reverse_iterator&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename range_result_iterator&lt;T&gt;::type <td><code>boost::reverse_iterator&lt; typename range_iterator&lt;T&gt;::type &gt;</code><br>
></code> <td>compile time</td>
<td >compile time</td> </tr>
<tr>
<a name="range_const_reverse_iterator"></a>
<td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt; typename range_const_iterator&lt;T&gt;::type &gt;</code>
<br>
<td>compile time</td>
</tr>
<tr>
<a name="range_reverse_result_iterator"></a>
<td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt; typename range_result_iterator&lt;T&gt;::type
&gt;</code>
<td>compile time</td>
</tr> </tr>
</table> </table>
</p> </p>
<p> <p>
The special metafunctions <code>range_result_iterator</code> and <code>range_reverse_result_iterator</code> The special metafunctions <code>range_result_iterator</code> and <code>range_reverse_result_iterator</code>
are not part of any Range concept, but they are very useful when implementing are not part of any Range concept, but they are very useful when implementing
certain Range classes like <a certain Range classes like <a href="utility_class.html#sub_range"><code>sub_range</code></a>
href="utility_class.html#sub_range"><code>sub_range</code></a> because of their because of their ability to select iterators based on constness.
ability to select iterators based on constness.
</p> </p>
<h4>Functions</h4> <h4>Functions</h4>
<p> <p>
<table border="1" cellpadding="5" > <table border="1" cellpadding="5">
<tr > <tr>
<th >Expression</th> <th>
<th >Return type</th> Expression</th>
<th >Returns</th> <th>
<th >Complexity</th> Return type</th>
<th>
Returns</th>
<th>
Complexity</th>
</tr> </tr>
<tr > <tr>
<a name="begin" ></a> <a name="begin"></a>
<td ><code >begin(x)</code></td> <td><code>begin(x)</code></td>
<td ><code >range_result_iterator&lt;X&gt;::type</code></td> <td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td ><code >t.begin()</code><br> <td><code>t.begin()</code><br>
<code >p.first</code><br> <code>p.first</code><br>
<code >a</code><br> <code>a</code><br>
<code>s</code> <code>s</code><br>
<td >constant time</td> <code>boost_range_begin(x)</code> otherwise
<td>constant time</td>
</tr> </tr>
<tr > <tr>
<a name="end" ></a> <a name="end"></a>
<td ><code >end(x)</code></td> <td><code>end(x)</code></td>
<td ><code >range_result_iterator&lt;X&gt;::type</code></td> <td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td ><code >t.end()</code><br> <td><code>t.end()</code><br>
<code >p.second</code><br> <code>p.second</code><br>
<code >a + sz</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> <code>s + std::char_traits&lt;X&gt;::length( s )</code> if <code>X</code> is <code>Char*</code>
<br> <br>
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br> <code>s + sz - 1</code> if <code>X</code> is <code>Char[sz]</code>
<br>
<code>boost_range_end(x)</code> otherwise
<td>linear if <code>X</code> is <code>Char*</code>
<td >linear if <code >X</code> is <code >Char*</code> <br> <br>
constant time otherwise</td> constant time otherwise</td>
</tr> </tr>
<tr > <tr>
<a name="empty" ></a> <a name="empty"></a>
<td ><code >empty(x)</code></td> <td><code>empty(x)</code></td>
<td ><code >bool</code></td> <td><code>bool</code></td>
<td ><code >begin(x) == end( x )</code><br> <td><code>begin(x) == end( x )</code><br>
<td >linear if <code >X</code> is <code >Char*</code> <br> <td>linear if <code>X</code> is <code>Char*</code>
<br>
constant time otherwise<br> constant time otherwise<br>
</td> </td>
</tr> </tr>
<tr > <tr>
<a name="size" ></a> <a name="size"></a>
<td ><code >size(x)</code></td> <td><code>size(x)</code></td>
<td ><code >range_size&lt;X&gt;::type</code></td> <td><code>range_size&lt;X&gt;::type</code></td>
<td ><code >t.size()</code><br> <td><code>t.size()</code><br>
<code>std::distance(p.first,p.second)</code><br> <code>std::distance(p.first,p.second)</code><br>
<code >sz</code><br> <code>sz</code><br>
<code>end(s) - s</code> <code>end(s) - s</code><br>
<code>boost_range_size(x)</code> otherwise
<td >linear if <code >X</code> is <code >Char*</code> <br> <td>linear if <code>X</code> is <code>Char*</code>
or if <code >std::distance()</code> is linear <br> <br>
or if <code>std::distance()</code> is linear
<br>
constant time otherwise</td> constant time otherwise</td>
</tr> </tr>
<tr > <tr>
<a name="rbegin" ></a> <a name="rbegin"></a>
<td ><code >rbegin(x)</code></td> <td><code>rbegin(x)</code></td>
<td ><code >range_reverse_result_iterator&lt;X&gt;::type</code></td> <td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td ><code >range_reverse_result_iterator&lt;X&gt;::type( end(x) )</code> <br> <td><code>range_reverse_result_iterator&lt;X&gt;::type( end(x) )</code>
<td >same as <code>end(x)</code> </td> <br>
<td>same as <code>end(x)</code>
</td>
</tr> </tr>
<tr > <tr>
<a name="rend" ></a> <a name="rend"></a>
<td ><code >rend(x)</code></td> <td><code>rend(x)</code></td>
<td ><code >range_reverse_result_iterator&lt;X&gt;::type</code></td> <td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td ><code >range_reverse_result_iterator&lt;X&gt;::type( begin(x) )</code> <td><code>range_reverse_result_iterator&lt;X&gt;::type( begin(x) )</code>
<td >same as <code>begin(x)</code></td> <td>same as <code>begin(x)</code></td>
</tr> </tr>
<tr > <tr>
<a name="const_begin" ></a> <a name="const_begin"></a>
<td ><code >const_begin(x)</code></td> <td><code>const_begin(x)</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type</code></td> <td><code>range_const_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type( begin(x) )</code> <td><code>range_const_iterator&lt;X&gt;::type( begin(x) )</code>
<br> <td >same as <code>begin(x)</code> </td> <br>
<td>same as <code>begin(x)</code>
</td>
</tr> </tr>
<tr > <tr>
<a name="const_end" ></a> <a name="const_end"></a>
<td ><code >const_end(x)</code></td> <td><code>const_end(x)</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type</code></td> <td><code>range_const_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type( end(x) )</code> <td><code>range_const_iterator&lt;X&gt;::type( end(x) )</code>
<td >same as <code>end(x)</code></td> <td>same as <code>end(x)</code></td>
</tr> </tr>
<tr > <tr>
<a name="const_rbegin" ></a> <a name="const_rbegin"></a>
<td ><code >const_rbegin(x)</code></td> <td><code>const_rbegin(x)</code></td>
<td ><code >range_const_reverse_iterator&lt;X&gt;::type</code></td> <td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_reverse_iterator&lt;X&gt;::type( rbegin(x) )</code> <td><code>range_const_reverse_iterator&lt;X&gt;::type( rbegin(x) )</code>
<br> <td >same as <code>rbegin(x)</code> </td> <br>
<td>same as <code>rbegin(x)</code>
</td>
</tr> </tr>
<tr > <tr>
<a name="const_rend" ></a> <a name="const_rend"></a>
<td ><code >const_rend(x)</code></td> <td><code>const_rend(x)</code></td>
<td ><code >range_const_reverse_iterator&lt;X&gt;::type</code></td> <td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_reverse_iterator&lt;X&gt;::type( rend(x) )</code> <td><code>range_const_reverse_iterator&lt;X&gt;::type( rend(x) )</code>
<td >same as <code>rend(x)</code></td> <td>same as <code>rend(x)</code></td>
</tr> </tr>
</table> </table>
</p> </p>
<p>
The special <code>const</code> functions are not part of any Range concept, but
are very useful when you want to document clearly that your code is read-only.
</p>
<hr>
<a name="minimal_interface"></a>
<h3>Extending the library</h3>
<ul>
<li><a href="#method1">Method 1: provide member functions and nested types</a></li>
<li><a href="#method2">Method 2: provide free-standing functions and specialize metafunctions</a></li>
</ul>
<a name="method1"></a>
<h4>Method 1: provide member functions and nested types</h4>
<p> <p>
The special <code>const</code> functions are not part of any Range concept, This procedure assumes that you have control over the types that should be made
but are very useful when you want to document clearly that your code is conformant to a Range concept. If not, see <a href="#method2">method 2</a>.
read-only.
</p> </p>
<hr>
<a name=minimal_interface></a> <h3>Extending the library</h3>
<p> <p>
The primary templates in this library are implemented such that standard The primary templates in this library are implemented such that standard
containers will work automatically and so will <code>boost::<a containers will work automatically and so will <code>boost::<a href="../../array/index.html">array</a></code>.
href=../../array/index.html>array</a></code>. Below is given an overview of Below is given an overview of which member functions and member types a class
which member functions and member types a class must specify to must specify to be useable as a certain Range concept.
be useable as a certain Range concept.
</p> </p>
<p> <p>
<table cellpadding="5" border="1"> <table cellpadding="5" border="1">
<tr> <tr>
<th>Member function</th> <th>
<th>Related concept</th> Member function</th>
<th>
Related concept</th>
<tr> <tr>
<td><code>begin()</code></td> <td><code>begin()</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td> <td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr> </tr>
<tr> <tr>
<td><code>end()</code> </td> <td><code>end()</code>
</td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td> <td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr> </tr>
<tr> <tr>
<td><code>size()</code></td> <td><code>size()</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td> <td><a href="range.html#forward_range">Forward Range</a></td>
</tr> </tr>
</table> </table>
</p> </p>
<p> <p>
Notice that <code>rbegin()</code> and <code>rend()</code> member functions Notice that <code>rbegin()</code> and <code>rend()</code> member functions are
are not needed even though the container can support bidirectional iteration. not needed even though the container can support bidirectional iteration.
</p> </p>
<p> <p>
The required member types are: The required member types are:
@ -493,8 +508,10 @@ be useable as a certain Range concept.
<p> <p>
<table cellpadding="5" border="1"> <table cellpadding="5" border="1">
<tr> <tr>
<th>Member type</th> <th>
<th>Related concept</th> Member type</th>
<th>
Related concept</th>
<tr> <tr>
<tr> <tr>
<td><code>value_type</code></td> <td><code>value_type</code></td>
@ -516,19 +533,224 @@ be useable as a certain Range concept.
<td><code>size_type</code></td> <td><code>size_type</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td> <td><a href="range.html#forward_range">Forward Range</a></td>
</tr> </tr>
</table> </table>
</p> </p>
<p> <p>
Again one should notice that member types <code>reverse_iterator</code> and Again one should notice that member types <code>reverse_iterator</code> and <code>const_reverse_iterator</code>
<code>const_reverse_iterator</code> are not needed. are not needed.
</p> </p>
<a name="method2"></a>
<h4>Method 2: provide free-standing functions and specialize metafunctions</h4>
<p>
This procedure assumes that you cannot (or do not wish to) change the types that should be made
conformant to a Range concept. If this is not true, see <a href="#method1">method 1</a>.
</p>
<p>
The primary templates in this library are implemented such that
certain functions are found via argument-dependent-lookup (ADL).
Below is given an overview of which free-standing functions a class
must specify to be useable as a certain Range concept.
Let <code>x</code> be a variable (<code>const</code> or mutable)
of the class in question.
</p>
<p>
<table cellpadding="5" border="1" ID="Table1">
<tr>
<th>
Function</th>
<th>
Related concept</th>
<tr>
<td><code>boost_range_begin(x)</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost_range_end(x)</code>
</td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boos_range_size(x)</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p><code>boost_range_begin()</code> and <code>boost_range_end()</code> must be
overloaded for both <code>const</code> and mutable reference arguments.
</p>
<p>
You must also specialize 3-5 metafunctions for your type <code>X</code>:
</p>
<p>
<table cellpadding="5" border="1" ID="Table2">
<tr>
<th>
Metafunction</th>
<th>
Related concept</th>
<tr>
<tr>
<td><code>boost::range_value</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost::range_iterator</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost::range_const_iterator</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost::range_difference</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td>
</tr>
<tr>
<td><code>boost::range_size</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p>
A complete example is given here:
</p>
<blockquote>
<pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>range</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=comment>// for std::iterator_traits, std::distance()</span>
<span class=keyword>namespace</span> <span class=identifier>Foo</span>
<span class=special>{</span>
<span class=comment>//
// Our sample UDT. A 'Pair'
// will work as a range when the stored
// elements are iterators.
//</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> <span class=identifier>Pair</span>
<span class=special>{</span>
<span class=identifier>T</span> <span class=identifier>first</span><span class=special>,</span> <span class=identifier>last</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace 'Foo'</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span>
<span class=special>{</span>
<span class=comment>//
// Specialize metafunctions. We must include the range.hpp header.
// We must open the 'boost' namespace.
//</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> <span class=identifier>range_value</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>iterator_traits</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>value_type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</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> <span class=identifier>range_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>T</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</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> <span class=identifier>range_const_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=comment>//
// Remark: this is defined similar to 'range_iterator'
// because the 'Pair' type does not distinguish
// between an iterator and a const_iterator.
//</span>
<span class=keyword>typedef</span> <span class=identifier>T</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</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> <span class=identifier>range_difference</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>iterator_traits</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>difference_type</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</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> <span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>static_assertion</span><span class=special>[</span> <span class=keyword>sizeof</span><span class=special>(</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=special>)</span> <span class=special>&gt;=</span>
<span class=keyword>sizeof</span><span class=special>(</span> <span class=keyword>typename</span> <span class=identifier>range_difference</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span> <span class=special>)</span> <span class=special>];</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace 'boost'</span>
<span class=keyword>namespace</span> <span class=identifier>Foo</span>
<span class=special>{</span>
<span class=comment>//
// The required functions. These should be defined in
// the same namespace as 'Pair', in this case
// in namespace 'Foo'.
//</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>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_begin</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</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>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_begin</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</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>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_end</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>;</span>
<span class=special>}</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>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_end</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>;</span>
<span class=special>}</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>inline</span> <span class=keyword>typename</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>boost_range_size</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>distance</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>);</span>
<span class=special>}</span>
<span class=special>}</span> <span class=comment>// namespace 'Foo'</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&gt;</span>
<span class=keyword>int</span> <span class=identifier>main</span><span class=special>()</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;::</span><span class=identifier>iterator</span> <span class=identifier>iter</span><span class=special>;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=identifier>vec</span><span class=special>;</span>
<span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=identifier>pair</span> <span class=special>=</span> <span class=special>{</span> <span class=identifier>vec</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span> <span class=identifier>vec</span><span class=special>.</span><span class=identifier>end</span><span class=special>()</span> <span class=special>};</span>
<span class=keyword>const</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;&amp;</span> <span class=identifier>cpair</span> <span class=special>=</span> <span class=identifier>pair</span><span class=special>;</span>
<span class=comment>//
// Notice that we call 'begin' etc with qualification.
//</span>
<span class=identifier>iter</span> <span class=identifier>i</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>iter</span> <span class=identifier>e</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>i</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>e</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>s</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>size</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>s</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>size</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>ri</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>rbegin</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>),</span>
<span class=identifier>re</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>rend</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=special>}</span>
</pre>
</blockquote>
<hr> <hr>
<p> <p>
(C) Copyright Thorsten Ottosen 2003-2004 (C) Copyright Thorsten Ottosen 2003-2004
</p> </p>
<br> <br>
<br> <br>
<br> <br>
@ -541,7 +763,5 @@ be useable as a certain Range concept.
<br> <br>
<br> <br>
<br> <br>
</body> </body>
</html> </html>

125
doc/example.cpp Normal file
View File

@ -0,0 +1,125 @@
#include <boost/range.hpp>
#include <iterator> // for std::iterator_traits, std::distance()
namespace Foo
{
//
// Our sample UDT. A 'Pair'
// will work as a range when the stored
// elements are iterators.
//
template< class T >
struct Pair
{
T first, last;
};
} // namespace 'Foo'
namespace boost
{
//
// Specialize metafunctions. We must include the range.hpp header.
// We must open the 'boost' namespace.
//
template< class T >
struct range_value< Foo::Pair<T> >
{
typedef typename std::iterator_traits<T>::value_type type;
};
template< class T >
struct range_iterator< Foo::Pair<T> >
{
typedef T type;
};
template< class T >
struct range_const_iterator< Foo::Pair<T> >
{
//
// Remark: this is defined similar to 'range_iterator'
// because the 'Pair' type does not distinguish
// between an iterator and a const_iterator.
//
typedef T type;
};
template< class T >
struct range_difference< Foo::Pair<T> >
{
typedef typename std::iterator_traits<T>::difference_type type;
};
template< class T >
struct range_size< Foo::Pair<T> >
{
int static_assertion[ sizeof( std::size_t ) >=
sizeof( typename range_difference< Foo::Pair<T> >::type ) ];
typedef std::size_t type;
};
} // namespace 'boost'
namespace Foo
{
//
// The required functions. These should be defined in
// the same namespace as 'Pair', in this case
// in namespace 'Foo'.
//
template< class T >
inline T boost_range_begin( Pair<T>& x )
{
return x.first;
}
template< class T >
inline T boost_range_begin( const Pair<T>& x )
{
return x.first;
}
template< class T >
inline T boost_range_end( Pair<T>& x )
{
return x.last;
}
template< class T >
inline T boost_range_end( const Pair<T>& x )
{
return x.last;
}
template< class T >
inline typename boost::range_size< Pair<T> >::type
boost_range_size( const Pair<T>& x )
{
return std::distance(x.first,x.last);
}
} // namespace 'Foo'
#include <vector>
int main()
{
typedef std::vector<int>::iterator iter;
std::vector<int> vec;
Foo::Pair<iter> pair = { vec.begin(), vec.end() };
const Foo::Pair<iter>& cpair = pair;
//
// Notice that we call 'begin' etc with qualification.
//
iter i = boost::begin( pair );
iter e = boost::end( pair );
i = boost::begin( cpair );
e = boost::end( cpair );
boost::range_size< Foo::Pair<iter> >::type s = boost::size( pair );
s = boost::size( cpair );
boost::range_const_reverse_iterator< Foo::Pair<iter> >::type
ri = boost::rbegin( cpair ),
re = boost::rend( cpair );
}

View File

@ -386,7 +386,7 @@ VAlign="top"><code>boost::range_const_reverse_iterator&ltX>::type</code></TD>
</TR> </TR>
<TR> <TR>
<TD VAlign="top">Beginning of range</TD> <TD VAlign="top">Beginning of range</TD>
<TD VAlign="top"><code>rboost::begin(a)</code></TD> <TD VAlign="top"><code>boost::rbegin(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if <TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code> <code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD> otherwise.</TD>
@ -394,7 +394,7 @@ otherwise.</TD>
<code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR> <code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR>
<TR> <TR>
<TD VAlign="top">End of range</TD> <TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>rboost::end(a)</code></TD> <TD VAlign="top"><code>boost::rend(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if <TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code> <code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD> otherwise.</TD>
@ -405,7 +405,7 @@ otherwise.</TD>
<h3>Complexity guarantees</h3> <h3>Complexity guarantees</h3>
<code>rboost::begin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>rboost::end(a)</code> <code>boost::rbegin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>boost::rend(a)</code>
has the same complexity as <code>boost::begin(a)</code> from <a has the same complexity as <code>boost::begin(a)</code> from <a
href="#forward_range">Forward Range</a>. href="#forward_range">Forward Range</a>.
@ -414,13 +414,13 @@ otherwise.</TD>
<Table border="1" cellpadding="5"> <Table border="1" cellpadding="5">
<TR> <TR>
<TD VAlign="top">Valid reverse range</TD> <TD VAlign="top">Valid reverse range</TD>
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[rboost::begin(a),rboost::end(a))</code> <TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[boost::rbegin(a),boost::rend(a))</code>
is a valid range, that is, <code>rboost::end(a)</code> is reachable from <code>rboost::begin(a)</code> is a valid range, that is, <code>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
in a finite number of increments.</TD> in a finite number of increments.</TD>
</TR> </TR>
<TR> <TR>
<TD VAlign="top">Completeness</TD> <TD VAlign="top">Completeness</TD>
<TD VAlign="top">An algorithm that iterates through the range <code>[rboost::begin(a),rboost::end(a))</code> <TD VAlign="top">An algorithm that iterates through the range <code>[boost::rbegin(a),boost::rend(a))</code>
will pass through every element of <code>a</code>.</TD> will pass through every element of <code>a</code>.</TD>
</tr> </tr>
</table> </table>