*** empty log message ***

[SVN r24430]
This commit is contained in:
Thorsten Jørgen Ottosen
2004-08-12 10:58:13 +00:00
parent 7d81f9a845
commit 8378643b44
13 changed files with 507 additions and 351 deletions

View File

@ -27,6 +27,8 @@
<li >
<a href="#Semantics" >Semantics</a>
</li>
<li>
<a href="#minimal_interface">Extending the library</a>
</ul>
<hr size="1" >
@ -35,7 +37,7 @@
Four types of objects are currently supported by the library:
<ul >
<li >
standard containers
standard-like containers
</li>
<li >
<code >std::pair&lt;iterator,iterator&gt;</code>
@ -49,125 +51,138 @@
</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#iterator_range"><code>iterator_range</code></a> implements the minimal interface required to make the class
a <a href="range.htm#forward_range">Forward Range</a>.
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>.
</p>
<p>
Please also see <a href="range.htm">Range concepts</a> for more details.
</p>
<a name="Synopsis" ></a>
<h3 >Synopsis</h3>
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
<p >
<pre>
namespace boost
{
//
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=comment>//
// Single Pass Range metafunctions
//
template< class T >
struct <a href="#value_type_of" >value_type_of</a>;
</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>;
template< class T >
struct <a href="#iterator_of" >iterator_of</a>;
</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>;
template< class T >
struct <a href="#const_iterator_of" >const_iterator_of</a>;
</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>;
//
</span><span class=comment>//
// Forward Range metafunctions
//
template< class T >
struct <a href="#difference_type_of" >difference_type_of</a>;
</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>;
template< class T >
struct <a href="#size_type_of" >size_type_of</a>;
</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>;
//
</span><span class=comment>//
// Bidirectional Range metafunctions
//
template< class T >
struct <a href="#reverse_iterator_of" >reverse_iterator_of</a>;
</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>;
template< class T >
struct <a href="#const_reverse_iterator_of" >const_reverse_iterator_of</a>;
</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>;
//
</span><span class=comment>//
// Special metafunctions
//
template< class T >
struct <a href="#result_iterator_of" >result_iterator_of</a>;
</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>;
template< class T >
struct <a href="#reverse_result_iterator_of" >reverse_result_iterator_of</a>;
</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>;
//
</span><span class=comment>//
// Single Pass Range functions
//
template< class T >
inline typename iterator_of&lt;T>::type
<a href="#begin" >begin</a>( T& c );
</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>);
template< class T >
inline typename const_iterator_of&lt;T>::type
<a href="#begin" >begin</a>( const T& c );
</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>);
template< class T >
inline typename iterator_of&lt;T>::type
<a href="#end" >end</a>( T& c );
</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>);
template< class T >
inline typename const_iterator_of&lt;T>::type
<a href="#end" >end</a>( const T& c );
</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>);
template< class T >
inline bool
<a href="#empty" >empty</a>( const T& c );
</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>);
//
</span><span class=comment>//
// Forward Range functions
//
template< class T >
inline typename size_type_of&lt;T>::type
<a href="#size" >size</a>( const T& c );
</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>);
//
</span><span class=comment>//
// Bidirectional Range functions
//
template< class T >
inline typename reverse_iterator_of&lt;T>::type
<a href="#rbegin" >rbegin</a>( T& c );
</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>);
template< class T >
inline typename const_reverse_iterator_of&lt;T>::type
<a href="#rbegin" >rbegin</a>( const T& c );
</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>);
template< class T >
inline typename reverse_iterator_of&lt;T>::type
<a href="#rend" >rend</a>( T& c );
</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>);
template< class T >
inline typename const_reverse_iterator_of&lt;T>::type
<a href="#rend" >rend</a>( const T& c );
} // namespace 'boost' </pre>
</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>
</p>
<a name="Semantics" ></a>
<h3 >Semantics</h3>
<a name="Semantics" ></a> <h3 >Semantics</h3>
<h4>notation</h4>
<p>
@ -206,10 +221,9 @@ namespace boost
</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.
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.
</p>
<h4>Metafunctions</h4>
<p>
@ -289,7 +303,8 @@ namespace boost
<tr >
<a name="reverse_result_iterator_of" ></a>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;::type ></code>
<td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;::type
></code>
<td >compile time</td>
</tr>
@ -297,12 +312,11 @@ namespace boost
</table>
</p>
<p>
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.
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.
</p>
<h4>Functions</h4>
@ -331,8 +345,8 @@ their ability to select iterators based on constness.
<td ><code >t.end()</code><br>
<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>
<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>
@ -365,20 +379,89 @@ their ability to select iterators based on constness.
<a name="rbegin" ></a>
<td ><code >rbegin(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( end(x)
)</code> <br> <td >same as <code>end(x)</code> </td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( end(x) )</code> <br>
<td >same as <code>end(x)</code> </td>
</tr>
<tr >
<a name="rend" ></a>
<td ><code >rend(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( begin(x)
)</code> <td >same as <code>begin(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;X&gt;::type( begin(x) )</code>
<td >same as <code>begin(x)</code></td>
</tr>
</table>
</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.
</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>
<p>

View File

@ -29,6 +29,9 @@
When it is possible to come up with one, the client might choose to construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code>
object.
</p>
<p>
Note that an <a href="utility_class.html#iter_range">iterator_range</a>
is somewhat more convenient than a <code>pair</code>. </p>
<li >
<i>Why is there not supplied more types or more functions?</i>
<p >
@ -58,11 +61,13 @@
</li>
<li>
<i>Should I use qualified syntax, for example
<blockquote><pre>boost::begin( r ); </pre></blockquote>
<blockquote><pre>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>); </span>
</pre></blockquote>
instead of
<blockquote>
<pre>using namespace boost;
begin( r )</pre></blockquote>
<pre><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>;</span>
<span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>)</span></pre></blockquote>
when calling functions in this library? If so, can I still rely on argument
dependent lookup (ADL) to kick in?</i>
<p>
@ -73,28 +78,31 @@ begin( r )</pre></blockquote>
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
it is best explained by some code: <blockquote>
<pre>
namespace boost
{
namespace range_detail
{
template< class T >
typename iterator_of&lt;T>:type begin( T& r )
{ /* normal implementation */ }
}
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=keyword>namespace </span><span class=identifier>range_detail
</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>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><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>)
</span><span class=special>{ </span><span class=comment>/* normal implementation */ </span><span class=special>}
</span><span class=special>}
template< class T >
typename iterator_of&lt;T>::type begin( T& r )
{
//
</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>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><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>)
</span><span class=special>{
</span><span class=comment>//
// Create ADL hook
//
using range_detail::begin;
return begin( r );
}
} </pre>
</span><span class=keyword>using </span><span class=identifier>range_detail</span><span class=special>::</span><span class=identifier>begin</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>);
</span><span class=special>}</span>
<span class=special>} </span>
</pre>
</blockquote>
Cool indeed!
</p>
</ol>

View File

@ -19,7 +19,7 @@
<h2 >History and Acknowledgement</h2><a name="History" ></a>
<p >
The library have been under way for a long time. Dietmar K<>hl originally
intended to submit an <code >array_traits&lt;&gt;</code> class template which
intended to submit an <code >array_traits</code> class template which
had most of the functionality present now, but only for arrays and standard
containers.
</p>
@ -48,9 +48,10 @@ C++ standard: <blockquote>
<p>
Special thanks goes to
<ul>
<li> Pavol Droba
<li> Pavel Vozenilek
<li> Jonathan Turkanis
<li> Pavol Droba for help with documentation and implementation
<li> Pavel Vozenilek for help with porting the library
<li> Jonathan Turkanis for help with documentation
<li> Hartmut Kaiser for being review manager
</ul>
</p>
<hr>

View File

@ -18,15 +18,23 @@
<h2>Introduction</h2>
<p>
When writing generic code that works with Standard Library containers, one often
finds it desirable to extend that code to work with other types that offer
When writing generic code that works with standard library containers, one
often finds it desirable to extend that code to work with other types that offer
enough functionality to satisfy the needs of the generic code, but in an altered
form. For example, raw arrays are often suitable for use with generic code that
works with containers, provided a suitable adapter is used. Likewise, null
terminated strings can be treated as containers of characters, if suitably
adapted. This library provides the means to adapt Standard Library containers,
adapted.
</p>
<p>
This library provides the means to adapt standard library
containers,
null terminated strings, <code>std::pairs</code> of iterators, and raw
arrays, such that the same generic code can work with them all.
arrays (and more), such that the same generic code can work with them all.
The basic idea is to add another layer of indirection using <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and
free-standing functions so syntactic and/or semantic differences can be removed.
</p>
<!-- <p>
@ -62,59 +70,67 @@ arrays?) </li>
):
<blockquote>
<pre >
<span class=comment>
//
// example: extracting bounds in a generic algorithm
//
template< typename ForwardRange, typename T >
inline typename boost::iterator_of< ForwardRange >::type
find( ForwardRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </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>iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>ForwardReadableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value </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>find</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>c </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>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
template< typename ForwardRange, typename T >
inline typename boost::const_iterator_of< ForwardRange >::type
find( const ForwardRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </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>const_iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>find</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardReadableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value </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>find</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>c </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>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
//
</span><span class=comment>//
// replace first value and return its index
//
template< class ForwardRange, class T >
inline typename boost::size_type_of< ForwardRange >::type
my_generic_replace( ForwardRange& c, const T& value, const T& replacement )
{
typename boost::iterator_of< ForwardRange >::type found = find( c, value );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>, </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>size_type_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>replacement </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>found </span><span class=special>= </span><span class=identifier>find</span><span class=special>( </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>value </span><span class=special>);
if( found != boost::end( c ) )
*found = replacement;
return std::distance( boost::begin( c ), found );
}
</span><span class=keyword>if</span><span class=special>( </span><span class=identifier>found </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>c </span><span class=special>) </span><span class=special>)
</span><span class=special>*</span><span class=identifier>found </span><span class=special>= </span><span class=identifier>replacement</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>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>found </span><span class=special>);
</span><span class=special>}
//
</span><span class=comment>//
// usage
//
const int N = 5;
std::vector<int> my_vector;
int values[] = { 1,2,3,4,5,6,7,8,9 };
my_vector.assign( values, values + 9 );
typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
char str_val[] = "a string";
char* str = str_val;
std::cout << my_generic_replace( my_vector, 4, 2 )
<< my_generic_replace( my_view, 4, 2 )
<< my_generic_replace( str, 'a', 'b' );
</span><span class=keyword>const </span><span class=keyword>int </span><span class=identifier>N </span><span class=special>= </span><span class=number>5</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>my_vector</span><span class=special>;
</span><span class=keyword>int </span><span class=identifier>values</span><span class=special>[] </span><span class=special>= </span><span class=special>{ </span><span class=number>1</span><span class=special>,</span><span class=number>2</span><span class=special>,</span><span class=number>3</span><span class=special>,</span><span class=number>4</span><span class=special>,</span><span class=number>5</span><span class=special>,</span><span class=number>6</span><span class=special>,</span><span class=number>7</span><span class=special>,</span><span class=number>8</span><span class=special>,</span><span class=number>9 </span><span class=special>};
</span>
<span class=identifier>my_vector</span><span class=special>.</span><span
class=identifier>assign</span><span class=special>( </span><span class=identifier>values</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>values </span><span class=special>) </span><span class=special>);</span>
</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>iterator</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt; </span><span class=identifier>my_view</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>my_vector </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>my_vector </span><span class=special>) </span><span class=special>+ </span><span class=identifier>N </span><span class=special>);
</span><span class=keyword>char </span><span class=identifier>str_val</span><span class=special>[] </span><span class=special>= </span><span class=string>&quot;a string&quot;</span><span class=special>;
</span><span class=keyword>char</span><span class=special>* </span><span class=identifier>str </span><span class=special>= </span><span class=identifier>str_val</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_vector</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_view</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=literal>'a'</span><span class=special>, </span><span class=literal>'b' </span><span class=special>);
</span>
<span class=comment>// prints '3', '5' and '0' </span>
</pre>
</blockquote>
By using the free-standing functions and metafunctions, the code automatically
works for all the types supported by this library. Notice that we have to
By using the free-standing functions and <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a>, the code automatically
works for all the types supported by this library; now and in the future.
Notice that we have to
provide two version of <code >find()</code> since we cannot forward a non-const
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
Forwarding Problem</a> ).

View File

@ -24,7 +24,7 @@
library. </p>
<p >
Notice that some compilers cannot do function template ordering properly. In
that case one must rely of <code >result_iterator_of&lt;&gt;</code> and a
that case one must rely of <code >result_iterator_of</code> and a
single function definition instead of
overloaded versions for const and non-const arguments.

View File

@ -80,9 +80,9 @@ category</a> of the underlying iterator type. Therefore
iterators support. See also <a href="style.html">terminology and style guidelines.</a>
for more information about naming of ranges.</p>
<p>
</p>
<p> The concepts described below specifies associated types as
<a href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and all
functions as free-standing functions to allow for a layer of indirection. </p>
<hr>
<a name="single_pass_range">

View File

@ -74,25 +74,36 @@
</p>
<p>
As an example, consider how we specify the interface of <code>std::sort()</code>.
The iterator-based version looks like this:
It might, however, be reasonable to specify only one category if the other
category does not matter. For example, the <a
href="utility_class.html#iter_range">iterator_range</a> can be constructed from
a Forward Range. This means that we do not care about what <i>value access</i>
properties the Range has. Similarly, a Readable Range will be one that has the
lowest possible <i>traversal</i> property (Single Pass).
</p>
<p>
As another example, consider how we specify the interface of <code>std::sort()</code>.
Algorithms are usually more cumbersome to specify the interface of since both <i>traversal</i>
and <i>value access</i> properties must be exactly defined. The iterator-based
version looks like this:
<pre>
template< class RandomAccessTraversalReadableWritableIterator >
void sort( RandomAccessTraversalReadableWritableIterator first,
RandomAccessTraversalReadableWritableIterator last );
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>sort</span><span class=special>( </span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=identifier>first</span><span class=special>,
</span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=identifier>last </span><span class=special>);</span>
</pre>
For ranges the interface becomes
<pre>
template< class RandomAccessReadableWritableRange >
void sort( RandomAccessReadableWritableRange& r );
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>RandomAccessReadableWritableRange </span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>sort</span><span class=special>( </span><span class=identifier>RandomAccessReadableWritableRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);</span>
</pre>
</p>
<p>
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004

View File

@ -37,7 +37,14 @@
Traversal Iterator</a> and should be used whenever fairly general code is needed.
The <code>sub_range</code> class is templated on an <a href="range.htm#forward_range">Forward
Range</a> and it is less general, but a bit easier to use since its template
argument is easier to specify.
argument is easier to specify. The biggest difference is, however, that a
<code>sub_range</code> can propagate constness because it knows what a
corresponding <code>const_iterator</code> is. </p>
<p>
Both classes can be used as ranges since they implement the <a
href="boost_range.html#minimal_interface">minimal interface</a>
required for this to work automatically.
</p>
<hr>
@ -49,105 +56,121 @@
are also provided for convenience.
</p>
<p>
If the template argument is not a model of Forward Traversal Iterator, one
can still use a subset of the interface. In particular, <code>size()</code>
requires Forward Traversal Iterators whereas <code>empty()</code> only
requires Single Pass Iterators.
If the template argument is not a model of Forward Traversal Iterator, one can
still use a subset of the interface. In particular, <code>size()</code> requires
Forward Traversal Iterators whereas <code>empty()</code> only requires Single
Pass Iterators.
</p>
<h3>Synopsis</h3>
<pre>
namespace boost
{
template< class ForwardTraversalIterator >
class iterator_range
{
iterator_range(); // not implemented
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>&gt;
</span><span class=keyword>class </span><span class=identifier>iterator_range
</span><span class=special>{
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// Forward Range types
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>value_type</span><span class=special>;
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>difference_type</span><span class=special>;
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>size_type</span><span class=special>;
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>iterator</span><span class=special>;
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>const_iterator</span><span class=special>;
public: // Forward Range types
typedef ... value_type;
typedef ... difference_type;
typedef ... size_type;
typedef ForwardTraversalIterator iterator;
typedef ForwardTraversalIterator const_iterator;
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator2 </span><span class=identifier>Begin</span><span class=special>, </span><span class=identifier>ForwardTraversalIterator2 </span><span class=identifier>End </span><span class=special>);
public: // construction, assignment
template< class ForwardTraversalIterator2 >
iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range( ForwardRange& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range( const ForwardRange& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range& operator=( ForwardRange& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range& operator=( const ForwardRange& r );
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// Forward Range functions
</span><span class=identifier>iterator </span><span class=identifier>begin</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=identifier>iterator </span><span class=identifier>end</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=identifier>size_type </span><span class=identifier>size</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=keyword>bool </span><span class=identifier>empty</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
public: // Forward Range functions
iterator begin() const;
iterator end() const;
size_type size() const;
bool empty() const;
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// convenience
</span><span class=keyword>operator </span><a
href="#unspecified_bool"><span class=identifier>unspecified_bool_type</span></a><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=special>};
public: // convenience
operator unspecified_bool_type() const;
};
</span><span class=comment>// stream output
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>Traits </span><span class=special>&gt;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>&gt;&amp;
</span><span class=keyword>operator</span><span class=special>&lt;&lt;( </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>&gt;&amp; </span><span class=identifier>Os</span><span class=special>,
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>ForwardTraversalIterator</span><span class=special>&gt;&amp; </span><span class=identifier>r </span><span class=special>);
// stream output
template< class ForwardTraversalIterator, class T, class Traits >
std::basic_ostream&lt;T,Traits>& operator<<( std::basic_ostream&lt;T,Traits>& Os,
const iterator_range&lt;ForwardTraversalIterator>& r );
</span><span class=comment>// comparison
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>&gt;
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>==( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>ForwardTraversalIterator</span><span class=special>&gt;&amp; </span><span class=identifier>l</span><span class=special>,
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>&gt;&amp; </span><span class=identifier>r </span><span class=special>);
// comparison
template< class ForwardTraversalIterator >
bool operator==( const iterator_range&lt;ForwardTraversalIterator>& l, const iterator_range&lt;ForwardTraversalIterator>& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>&gt;
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>!=( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>ForwardTraversalIterator</span><span class=special>&gt;&amp; </span><span class=identifier>l</span><span class=special>,
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>&gt;&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardTraversalIterator >
bool operator!=( const iterator_range&lt;ForwardTraversalIterator>& l, const iterator_range&lt;ForwardTraversalIterator>& r );
</span><span class=comment>// external construction
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=identifier>ForwardTraversalIterator </span><span class=special>&gt;
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>Begin</span><span class=special>,
</span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>End </span><span class=special>);
// external construction
template< class ForwardTraversalIterator >
iterator_range< ForwardTraversalIterator >
make_iterator_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range< typename iterator_of&lt;ForwardRange>::type >
make_iterator_range( ForwardRange& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange >
iterator_range< typename const_iterator_of&lt;ForwardRange>::type >
make_iterator_range( const ForwardRange& r );
</span><span class=comment>// convenience
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>Sequence</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>Sequence </span><a href="#copy_range"><span
class=identifier>copy_range</span></a><span class=special>( </span><span
class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
// convenience
template< class Sequence, class ForwardRange >
Sequence copy_range( const ForwardRange& r );
template< class Sequence, class ForwardRange, class Func >
Sequence transform_range( const ForwardRange& r, Func func );
} // namespace 'boost'
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>Sequence</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>Func </span><span class=special>&gt;
</span><span class=identifier>Sequence </span><a
href="#transform_range"><span
class=identifier>transform_range</span></a><span class=special>( </span><span
class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>Func </span><span class=identifier>func </span><span class=special>);
</span>
<span class=special>} </span><span class=comment>// namespace 'boost'</span>
</pre>
<p>
It is worth noticing that the templated constructors and assignment operators
allow conversion from <code>iterator_range&lt;iterator></code> to
<code>iterator_range&lt;const_iterator></code>. If an instance of
If an instance of
<code>iterator_range</code> is constructed by a client with two iterators, the
client must ensure that the two iterators delimit a valid closed-open range
<code>[begin,end)</code>.
</p>
<p>
It is worth noticing that the templated constructors and assignment operators
allow conversion from <code>iterator_range&lt;iterator></code> to
<code>iterator_range&lt;const_iterator></code>. Similarly, since the comparison
operators have two template arguments, we can compare ranges whenever the
iterators are comparable; for example when we are dealing with const and
non-const iterators from the same container. </p>
<h3>Details member functions</h3>
<a name="unspecified_bool"></a>
<code>operator unspecified_bool_type() const; </code>
<blockquote>
Returns <code>!empty().</code>
<!--
<b>Example</b> <code> iterator_range<const char*> r( "a string" ); if( r )
do_something();</code>-->
@ -155,12 +178,13 @@ do_something();</code>-->
<h3>Details functions</h3>
<a name="copy_range"></a>
<code>Sequence copy_range( const ForwardRange& r );</code>
<blockquote>
Constructs a new sequence of the specified type from the elements
in the given range.
</blockquote>
<a name="transform_range"></a>
<code>Sequence transform_range( const ForwardRange& r, Func func );</code>
<blockquote>
Constructs a new sequence from the elements in the range,
@ -175,48 +199,67 @@ The <code>sub_range</code> class inherits all its functionality
from the <a href="#iter_range"><code>iterator_range</code></a> class.
The <code>sub_range</code> class is often easier to use because
one must specify the <a href="range.html#forward_range">Forward Range</a>
template argument instead of an iterator.
template argument instead of an iterator. Moreover, the <code>sub_range</code>
class can propagate constness since it knows what a corresponding
<code>const_iterator</code> is.
<h3>Synopsis</h3>
<pre>
namespace boost
{
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=keyword>class </span><span class=identifier>sub_range </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>result_iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=special>{
</span><span class=keyword>public</span><span class=special>: </span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span
class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>const_iterator</span><span class=special>;</span>
template< class ForwardRange >
class sub_range : public iterator_range< typename result_iterator_of&lt;ForwardRange>::type >
{
public: // construction, assignment
template< class ForwardTraversalIterator >
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
<span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>Begin</span><span class=special>, </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>End </span><span class=special>);
template< class ForwardRange2 >
sub_range( ForwardRange2& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange2 >
sub_range( const Range2& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>Range2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange2 >
sub_range& operator=( ForwardRange2& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
template< class ForwardRange2 >
sub_range& operator=( const ForwardRange2& r );
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
<span class=keyword>public</span><span class=special>:
</span><span class=identifier>iterator </span><span
class=identifier>begin</span><span class=special>();
</span><span class=identifier>const_iterator </span><span class=identifier>begin</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=identifier>iterator </span><span class=identifier>end</span><span class=special>();
</span><span class=identifier>const_iterator </span><span class=identifier>end</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
public:
// rest of interface inherited from iterator_range
};
} // namespace 'boost'
<span class=keyword>public</span><span class=special>:
</span><span class=comment>// rest of interface inherited from iterator_range
</span><span class=special>};
</span>
<span class=special>} </span><span class=comment>// namespace 'boost'</span>
</pre>
<p>
The class should be trivial to use, an example with strings is shown below.
The class should be trivial to use as seen below.
Imagine that we have an algorithm that searches for a sub-string in a string.
The
result is an <code>iterator_range</code>, that delimits the match. We need to
store the result
from this algorithm. Here is an example of how we can do it with and without
<code>sub_range</code>
<pre>
typedef sub_range<std::string> sub_string;
std::string s = "something";
sub_string ss( s );
sub_string ss2( begin( s ), begin( s ) + 2 );</pre>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>str</span><span class=special>(</span><span class=string>&quot;hello&quot;</span><span class=special>);
</span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>&gt; </span><span class=identifier>ir </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>&quot;ll&quot; </span><span class=special>);
</span><span class=identifier>sub_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>sub </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>&quot;ll&quot; </span><span class=special>);</span>
</pre>
</p>
<hr>
<p>
@ -236,6 +279,7 @@ namespace boost
<br>
<br>
</body>
</html>

View File

@ -51,8 +51,6 @@ namespace boost {
template<typename IteratorT>
class iterator_range
{
iterator_range(); // not implemented
public:
//! this type
typedef iterator_range<IteratorT> type;
@ -185,9 +183,9 @@ namespace boost {
/*!
Compare operands for equality
*/
template< class IteratorT >
template< class IteratorT, class IteratorT2 >
inline bool operator==( const iterator_range<IteratorT>& l,
const iterator_range<IteratorT>& r )
const iterator_range<IteratorT2>& r )
{
return ! (l != r);
}
@ -196,9 +194,9 @@ namespace boost {
/*!
Compare operands for non-equality
*/
template< class IteratorT >
template< class IteratorT, class IteratorT2 >
inline bool operator!=( const iterator_range<IteratorT>& l,
const iterator_range<IteratorT>& r )
const iterator_range<IteratorT2>& r )
{
return l.begin() != r.begin() || l.end() != r.end();
}

View File

@ -23,15 +23,13 @@ namespace boost
template< class ForwardRange >
class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME result_iterator_of<ForwardRange>::type >
{
sub_range(); // not implemented
typedef BOOST_DEDUCED_TYPENAME result_iterator_of<ForwardRange>::type iterator_t;
typedef iterator_range< iterator_t > base;
public:
using base::iterator;
using base::const_iterator;
using base::value_type;
using BOOST_DEDUCED_TYPENAME base::value_type;
using BOOST_DEDUCED_TYPENAME base::iterator;
typedef BOOST_DEDUCED_TYPENAME const_iterator_of<ForwardRange>::type const_iterator;
typedef BOOST_DEDUCED_TYPENAME difference_type_of<ForwardRange>::type difference_type;
typedef BOOST_DEDUCED_TYPENAME size_type_of<ForwardRange>::type size_type;
@ -63,10 +61,13 @@ namespace boost
return *this;
}
size_type size() const
{
return base::size();
}
public:
iterator begin() { return base::begin(); }
const_iterator begin() const { return base::begin(); }
iterator end() { return base::end(); }
const_iterator end() const { return base::end(); }
size_type size() const { return std::distance( begin(), end() ); }
};

View File

@ -1,28 +0,0 @@
// Boost.Range library
//
// Copyright Thorsten Ottosen 2003-2004. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//
#ifndef BOOST_RANGE_TYPES_HPP
#define BOOST_RANGE_TYPES_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/size_type.hpp>
#include <boost/range/difference_type.hpp>
#include <boost/range/result_iterator.hpp>
#include <boost/range/reverse_iterator.hpp>
#include <boost/range/const_reverse_iterator.hpp>
#include <boost/range/reverse_result_iterator.hpp>
#endif

View File

@ -17,6 +17,8 @@
#include <boost/range/functions.hpp >
#include <boost/range/metafunctions.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <algorithm>
#include <vector>
@ -24,7 +26,6 @@
namespace
{
//
// example: extrating bounds in a generic algorithm
//
@ -58,12 +59,12 @@ namespace
}
int main()
void check_algorithm()
{
//
// usage
//
const int N = 5;
const unsigned N = 5;
std::vector<int> my_vector;
int values[] = { 1,2,3,4,5,6,7,8,9 };
my_vector.assign( values, values + 9 );
@ -73,8 +74,24 @@ int main()
char str_val[] = "a string";
char* str = str_val;
std::cout << my_generic_replace( my_vector, 4, 2 )
<< my_generic_replace( my_view, 4, 2 )
<< my_generic_replace( str, 'a', 'b' );
return 0;
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3u );
BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
BOOST_CHECK_EQUAL( my_generic_replace( str, 'a', 'b' ), 0u );
}
#include <boost/test/included/unit_test_framework.hpp>
using boost::unit_test_framework::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
test->add( BOOST_TEST_CASE( &check_algorithm ) );
return test;
}

View File

@ -60,11 +60,13 @@ void check_iterator_range()
typedef sub_range<const string> csrange;
srange s = r;
BOOST_CHECK( r == r );
BOOST_CHECK( s == r );
s = make_iterator_range( str );
csrange s2 = r;
s2 = r2;
s2 = make_iterator_range( cstr );
BOOST_CHECK( r2 == r2 );
BOOST_CHECK( s2 != r2 );
s2 = make_iterator_range( str );
BOOST_CHECK( !(s != s) );
@ -88,6 +90,9 @@ void check_iterator_range()
string res = copy_range<string>( r );
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
res = transform_range<string>( r, add_one() );
BOOST_CHECK( res[0] == 'i' );
BOOST_CHECK( *res.rbegin() == 'e' );
r.empty();
s.empty();