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

@ -5,33 +5,29 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table>
<tr>
<td><img src="../../../boost.png" width="100%" border="0"></td>
<td><h1><br>
Boost.Range </h1></td>
Boost.Range
</h1>
</td>
</tr>
</table>
<h2>Synopsis and Reference </h2>
<h2>Synopsis and Reference
</h2>
<ul>
<li>
<a href="#overview">Overview</a>
<li>
<a href="#Synopsis">Synopsis</a>
</li>
<li>
<a href="#Semantics">Semantics</a>
</li>
<li>
<a href="#minimal_interface">Extending the library</a>
<a href="#minimal_interface">Extending the library</a></li>
</ul>
<hr size="1">
<a name="overview"></a>
<h3>Overview</h3>
<p>
@ -39,10 +35,8 @@
<ul>
<li>
standard-like containers
</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>)
@ -50,29 +44,24 @@
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
</li>
<li>
built-in arrays
</li>
</ul>
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.html#forward_range">Forward Range</a>.
</p>
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.html#forward_range">Forward
Range</a>
.
<P></P>
<p>
Please also see <a href="range.html">Range concepts</a> for more details.
</p>
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
<a name="Synopsis"></a>
<h3>Synopsis</h3>
<p>
<pre>
<span class=keyword>namespace </span><span class=identifier>boost</span>
<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>
</pre>
</p>
<a name="Semantics" ></a> <h3 >Semantics</h3>
<P></P>
<a name="Semantics"></a>
<h3>Semantics</h3>
<h4>notation</h4>
<p>
<table cellpadding="5" border="1">
<tr>
<th>Type
<th>Object
<th>Describes
<th>
Type
<th>
Object
<th>
Describes
</tr>
<tr>
<td><code>X</code>
<td><code>x</code>
<td>any type
</tr>
<td>any type</td>
<tr>
<td><code>T</code> </td>
<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>
<td>denotes <code>std::pair&lt;iterator,iterator&gt;</code></td>
<tr>
<td><code>A[sz]</code>
<td><code>a</code>
@ -242,23 +232,25 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<tr>
<td><code>Char*</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>
</table>
</p>
<p>
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.
line will describe the primary template, the second line pairs of iterators,
the third line arrays and the last line null-terminated strings.
</p>
<h4>Metafunctions</h4>
<p>
<table border="1" cellpadding="5">
<tr>
<th >Expression</th>
<th >Return type</th>
<th >Complexity</th>
<th>
Expression</th>
<th>
Return type</th>
<th>
Complexity</th>
</tr>
<tr>
<a name="range_value"></a>
@ -291,8 +283,7 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<a name="range_difference"></a>
<td><code>range_difference&lt;X&gt;::type</code></td>
<td><code>T::difference_type</code><br>
<code
>boost::iterator_difference&lt;P::first_type&gt;::type</code><br>
<code>boost::iterator_difference&lt;P::first_type&gt;::type</code><br>
<code>std::ptrdiff_t</code><br>
<code>std::ptrdiff_t</code><br>
<td>compile time</td>
@ -309,51 +300,52 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<tr>
<a name="range_result_iterator"></a>
<td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td ><code >range_const_iterator&lt;X&gt;::type</code> if <code
>X</code> is <code >const</code> <br>
<code >range_iterator&lt;X&gt;::type</code> otherwise </td>
<td><code>range_const_iterator&lt;X&gt;::type</code> if <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><code>boost::reverse_iterator&lt; typename range_iterator&lt;T&gt;::type &gt;</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>
<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< typename range_result_iterator&lt;T&gt;::type
></code>
<td><code>boost::reverse_iterator&lt; typename range_result_iterator&lt;T&gt;::type
&gt;</code>
<td>compile time</td>
</tr>
</table>
</p>
<p>
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
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.
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.
</p>
<h4>Functions</h4>
<p>
<table border="1" cellpadding="5">
<tr>
<th >Expression</th>
<th >Return type</th>
<th >Returns</th>
<th >Complexity</th>
<th>
Expression</th>
<th>
Return type</th>
<th>
Returns</th>
<th>
Complexity</th>
</tr>
<tr>
<a name="begin"></a>
@ -362,7 +354,8 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<td><code>t.begin()</code><br>
<code>p.first</code><br>
<code>a</code><br>
<code>s</code>
<code>s</code><br>
<code>boost_range_begin(x)</code> otherwise
<td>constant time</td>
</tr>
<tr>
@ -374,10 +367,12 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<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>
<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> <br>
<td>linear if <code>X</code> is <code>Char*</code>
<br>
constant time otherwise</td>
</tr>
<tr>
@ -385,7 +380,8 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<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>
<td>linear if <code>X</code> is <code>Char*</code>
<br>
constant time otherwise<br>
</td>
</tr>
@ -396,18 +392,22 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<td><code>t.size()</code><br>
<code>std::distance(p.first,p.second)</code><br>
<code>sz</code><br>
<code>end(s) - s</code>
<td >linear if <code >X</code> is <code >Char*</code> <br>
or if <code >std::distance()</code> is linear <br>
<code>end(s) - s</code><br>
<code>boost_range_size(x)</code> otherwise
<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>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 >same as <code>end(x)</code> </td>
<td><code>range_reverse_result_iterator&lt;X&gt;::type( end(x) )</code>
<br>
<td>same as <code>end(x)</code>
</td>
</tr>
<tr>
<a name="rend"></a>
@ -421,7 +421,9 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<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( begin(x) )</code>
<br> <td >same as <code>begin(x)</code> </td>
<br>
<td>same as <code>begin(x)</code>
</td>
</tr>
<tr>
<a name="const_end"></a>
@ -435,7 +437,9 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<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( rbegin(x) )</code>
<br> <td >same as <code>rbegin(x)</code> </td>
<br>
<td>same as <code>rbegin(x)</code>
</td>
</tr>
<tr>
<a name="const_rend"></a>
@ -444,48 +448,59 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<td><code>range_const_reverse_iterator&lt;X&gt;::type( rend(x) )</code>
<td>same as <code>rend(x)</code></td>
</tr>
</table>
</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>
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.
This procedure assumes that you have control over the types that should be made
conformant to a Range concept. If not, see <a href="#method2">method 2</a>.
</p>
<hr>
<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.
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>
<th>
Member function</th>
<th>
Related concept</th>
<tr>
<td><code>begin()</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</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>
</tr>
<tr>
<td><code>size()</code></td>
<td><a href="range.html#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.
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:
@ -493,8 +508,10 @@ be useable as a certain Range concept.
<p>
<table cellpadding="5" border="1">
<tr>
<th>Member type</th>
<th>Related concept</th>
<th>
Member type</th>
<th>
Related concept</th>
<tr>
<tr>
<td><code>value_type</code></td>
@ -516,19 +533,224 @@ be useable as a certain Range concept.
<td><code>size_type</code></td>
<td><a href="range.html#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.
Again one should notice that member types <code>reverse_iterator</code> and <code>const_reverse_iterator</code>
are not needed.
</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>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
@ -541,7 +763,5 @@ be useable as a certain Range concept.
<br>
<br>
<br>
</body>
</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>
<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
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
@ -394,7 +394,7 @@ otherwise.</TD>
<code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR>
<TR>
<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
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
@ -405,7 +405,7 @@ otherwise.</TD>
<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
href="#forward_range">Forward Range</a>.
@ -414,13 +414,13 @@ otherwise.</TD>
<Table border="1" cellpadding="5">
<TR>
<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>
is a valid range, that is, <code>rboost::end(a)</code> is reachable from <code>rboost::begin(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>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
in a finite number of increments.</TD>
</TR>
<TR>
<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>
</tr>
</table>