forked from boostorg/range
*** empty log message ***
[SVN r24430]
This commit is contained in:
@ -27,6 +27,8 @@
|
|||||||
<li >
|
<li >
|
||||||
<a href="#Semantics" >Semantics</a>
|
<a href="#Semantics" >Semantics</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#minimal_interface">Extending the library</a>
|
||||||
</ul>
|
</ul>
|
||||||
<hr size="1" >
|
<hr size="1" >
|
||||||
|
|
||||||
@ -35,7 +37,7 @@
|
|||||||
Four types of objects are currently supported by the library:
|
Four types of objects are currently supported by the library:
|
||||||
<ul >
|
<ul >
|
||||||
<li >
|
<li >
|
||||||
standard containers
|
standard-like containers
|
||||||
</li>
|
</li>
|
||||||
<li >
|
<li >
|
||||||
<code >std::pair<iterator,iterator></code>
|
<code >std::pair<iterator,iterator></code>
|
||||||
@ -48,126 +50,139 @@
|
|||||||
built-in arrays
|
built-in arrays
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Even though the behavior of the primary templates are exactly such
|
Even though the behavior of the primary templates are exactly such that standard
|
||||||
that standard containers will be supported by default, the requirements
|
containers will be supported by default, the requirements are much lower than
|
||||||
are much lower than the standard container requirements. For example,
|
the standard container requirements. For example, the utility class <a
|
||||||
the utility class <a href="utility_class#iterator_range"><code>iterator_range</code></a> implements the minimal interface required to make the class
|
href="utility_class.html#iter_range"><code>iterator_range</code></a> implements
|
||||||
a <a href="range.htm#forward_range">Forward Range</a>.
|
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>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Please also see <a href="range.htm">Range concepts</a> for more details.
|
Please also see <a href="range.htm">Range concepts</a> for more details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a name="Synopsis" ></a>
|
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
|
||||||
<h3 >Synopsis</h3>
|
|
||||||
|
|
||||||
<p >
|
<p >
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
namespace boost
|
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||||
{
|
<span class=special>{
|
||||||
//
|
</span><span class=comment>//
|
||||||
// Single Pass Range metafunctions
|
// Single Pass Range metafunctions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#value_type_of" >value_type_of</a>;
|
</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 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#iterator_of" >iterator_of</a>;
|
</span><span class=keyword>struct </span><a href="#iterator_of"><span
|
||||||
|
class=identifier>iterator_of</span></a><span class=special>;
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#const_iterator_of" >const_iterator_of</a>;
|
</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
|
// Forward Range metafunctions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#difference_type_of" >difference_type_of</a>;
|
</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 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#size_type_of" >size_type_of</a>;
|
</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
|
// Bidirectional Range metafunctions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#reverse_iterator_of" >reverse_iterator_of</a>;
|
</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 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#const_reverse_iterator_of" >const_reverse_iterator_of</a>;
|
</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
|
// Special metafunctions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#result_iterator_of" >result_iterator_of</a>;
|
</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 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
struct <a href="#reverse_result_iterator_of" >reverse_result_iterator_of</a>;
|
</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
|
// Single Pass Range functions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#begin" >begin</a>( T& c );
|
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename const_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#begin" >begin</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#end" >end</a>( T& c );
|
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename const_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#end" >end</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline bool
|
</span><span class=keyword></span><span class=keyword>bool
|
||||||
<a href="#empty" >empty</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
//
|
</span><span class=comment>//
|
||||||
// Forward Range functions
|
// Forward Range functions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename size_type_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>size_type_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#size" >size</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
//
|
</span><span class=comment>//
|
||||||
// Bidirectional Range functions
|
// Bidirectional Range functions
|
||||||
//
|
//
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename reverse_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>reverse_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#rbegin" >rbegin</a>( T& c );
|
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename const_reverse_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_reverse_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#rbegin" >rbegin</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename reverse_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>reverse_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#rend" >rend</a>( T& c );
|
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
inline typename const_reverse_iterator_of<T>::type
|
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>const_reverse_iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||||
<a href="#rend" >rend</a>( const T& c );
|
</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>& </span><span class=identifier>c </span><span class=special>);
|
||||||
} // namespace 'boost' </pre>
|
</span>
|
||||||
|
<span class=special>} </span><span class=comment>// namespace 'boost'
|
||||||
|
</span></pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a name="Semantics" ></a>
|
<a name="Semantics" ></a> <h3 >Semantics</h3>
|
||||||
<h3 >Semantics</h3>
|
|
||||||
|
|
||||||
<h4>notation</h4>
|
<h4>notation</h4>
|
||||||
<p>
|
<p>
|
||||||
@ -179,7 +194,7 @@ namespace boost
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>X</code>
|
<td><code>X</code>
|
||||||
<td> <code>x</code>
|
<td><code>x</code>
|
||||||
<td>any type
|
<td>any type
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -206,10 +221,9 @@ namespace boost
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Please notice in tables below that when four lines appear in a
|
Please notice in tables below that when four lines appear in a cell, the first
|
||||||
cell, the first line will describe the primary template, the second
|
line will describe the primary template, the second line pairs of iterators, the
|
||||||
line pairs of iterators, the third line arrays and the last line
|
third line arrays and the last line null-terminated strings.
|
||||||
null-terminated strings.
|
|
||||||
</p>
|
</p>
|
||||||
<h4>Metafunctions</h4>
|
<h4>Metafunctions</h4>
|
||||||
<p>
|
<p>
|
||||||
@ -232,16 +246,16 @@ namespace boost
|
|||||||
<a name="iterator_of" ></a>
|
<a name="iterator_of" ></a>
|
||||||
<td ><code >iterator_of<X>::type</code></td>
|
<td ><code >iterator_of<X>::type</code></td>
|
||||||
<td ><code >T::iterator</code><br>
|
<td ><code >T::iterator</code><br>
|
||||||
<code >P::first_type</code><br>
|
<code >P::first_type</code><br>
|
||||||
<code >A*</code><br>
|
<code >A*</code><br>
|
||||||
<code>Char*</code>
|
<code>Char*</code>
|
||||||
<td >compile time</td>
|
<td >compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr >
|
||||||
<a name="const_iterator_of" ></a>
|
<a name="const_iterator_of" ></a>
|
||||||
<td ><code >const_iterator_of<X>::type</code></td>
|
<td ><code >const_iterator_of<X>::type</code></td>
|
||||||
<td ><code >T::const_iterator</code><br>
|
<td ><code >T::const_iterator</code><br>
|
||||||
<code >P::first_type</code><br>
|
<code >P::first_type</code><br>
|
||||||
<code >const A*</code><br>
|
<code >const A*</code><br>
|
||||||
<code>const Char*</code>
|
<code>const Char*</code>
|
||||||
<td >compile time</td>
|
<td >compile time</td>
|
||||||
@ -250,10 +264,10 @@ namespace boost
|
|||||||
<a name="difference_type_of" ></a>
|
<a name="difference_type_of" ></a>
|
||||||
<td ><code >difference_type_of<X>::type</code></td>
|
<td ><code >difference_type_of<X>::type</code></td>
|
||||||
<td ><code >T::difference_type</code><br>
|
<td ><code >T::difference_type</code><br>
|
||||||
<code
|
<code
|
||||||
>boost_iterator_difference<P::first_type>::type</code><br>
|
>boost_iterator_difference<P::first_type>::type</code><br>
|
||||||
<code >std::ptrdiff_t</code><br>
|
<code >std::ptrdiff_t</code><br>
|
||||||
<code >std::ptrdiff_t</code><br>
|
<code >std::ptrdiff_t</code><br>
|
||||||
<td >compile time</td>
|
<td >compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr >
|
||||||
@ -268,8 +282,8 @@ namespace boost
|
|||||||
<tr >
|
<tr >
|
||||||
<a name="result_iterator_of" ></a>
|
<a name="result_iterator_of" ></a>
|
||||||
<td ><code >result_iterator_of<X>::type</code></td>
|
<td ><code >result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >const_iterator_of<X>::type</code> if <code
|
<td ><code >const_iterator_of<X>::type</code> if <code
|
||||||
>X</code> is <code >const</code> <br>
|
>X</code> is <code >const</code> <br>
|
||||||
<code >iterator_of<X>::type</code> otherwise </td>
|
<code >iterator_of<X>::type</code> otherwise </td>
|
||||||
<td >compile time</td>
|
<td >compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -289,7 +303,8 @@ namespace boost
|
|||||||
<tr >
|
<tr >
|
||||||
<a name="reverse_result_iterator_of" ></a>
|
<a name="reverse_result_iterator_of" ></a>
|
||||||
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >boost::reverse_iterator< typename result_iterator_of<T>::type ></code>
|
<td ><code >boost::reverse_iterator< typename result_iterator_of<T>::type
|
||||||
|
></code>
|
||||||
<td >compile time</td>
|
<td >compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -297,12 +312,11 @@ namespace boost
|
|||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The special metafunctions <code>result_iterator_of</code> and
|
The special metafunctions <code>result_iterator_of</code> and <code>reverse_result_iterator_of</code>
|
||||||
<code>reverse_result_iterator_of</code> are not part
|
are not part of any Range concept, but they are very useful when implementing
|
||||||
of any Range concept, but they are very useful when implementing certain
|
certain Range classes like <a
|
||||||
Range classes like <a
|
href="utility_class.html#sub_range"><code>sub_range</code></a> because of their
|
||||||
href="utility_class.html#sub_range"><code>sub_range</code></a> because of
|
ability to select iterators based on constness.
|
||||||
their ability to select iterators based on constness.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>Functions</h4>
|
<h4>Functions</h4>
|
||||||
@ -319,7 +333,7 @@ their ability to select iterators based on constness.
|
|||||||
<td ><code >begin(x)</code></td>
|
<td ><code >begin(x)</code></td>
|
||||||
<td ><code >result_iterator_of<X>::type</code></td>
|
<td ><code >result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >t.begin()</code><br>
|
<td ><code >t.begin()</code><br>
|
||||||
<code >p.first</code><br>
|
<code >p.first</code><br>
|
||||||
<code >a</code><br>
|
<code >a</code><br>
|
||||||
<code>s</code>
|
<code>s</code>
|
||||||
<td >constant time</td>
|
<td >constant time</td>
|
||||||
@ -329,13 +343,13 @@ their ability to select iterators based on constness.
|
|||||||
<td ><code >end(x)</code></td>
|
<td ><code >end(x)</code></td>
|
||||||
<td ><code >result_iterator_of<X>::type</code></td>
|
<td ><code >result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >t.end()</code><br>
|
<td ><code >t.end()</code><br>
|
||||||
<code >p.second</code><br>
|
<code >p.second</code><br>
|
||||||
<code >a + sz</code> <br>
|
<code >a + sz</code> <br>
|
||||||
<code >s + std::char_traits<X>::length( s )</code> if
|
<code >s + std::char_traits<X>::length( s )</code> if <code >X</code> is <code >Char*</code>
|
||||||
<code >X</code> is <code >Char*</code><br>
|
<br>
|
||||||
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br>
|
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br>
|
||||||
|
|
||||||
|
|
||||||
<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>
|
constant time otherwise</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -353,9 +367,9 @@ their ability to select iterators based on constness.
|
|||||||
<td ><code >size(x)</code></td>
|
<td ><code >size(x)</code></td>
|
||||||
<td ><code >size_type_of<X>::type</code></td>
|
<td ><code >size_type_of<X>::type</code></td>
|
||||||
<td ><code >t.size()</code><br>
|
<td ><code >t.size()</code><br>
|
||||||
<code>std::distance(p.first,p.second)</code><br>
|
<code>std::distance(p.first,p.second)</code><br>
|
||||||
<code >sz</code><br>
|
<code >sz</code><br>
|
||||||
<code>end(s) - s</code>
|
<code>end(s) - s</code>
|
||||||
|
|
||||||
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
||||||
or if <code >std::distance()</code> is linear <br>
|
or if <code >std::distance()</code> is linear <br>
|
||||||
@ -365,22 +379,91 @@ their ability to select iterators based on constness.
|
|||||||
<a name="rbegin" ></a>
|
<a name="rbegin" ></a>
|
||||||
<td ><code >rbegin(x)</code></td>
|
<td ><code >rbegin(x)</code></td>
|
||||||
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >reverse_result_iterator_of<X>::type( end(x)
|
<td ><code >reverse_result_iterator_of<X>::type( end(x) )</code> <br>
|
||||||
)</code> <br> <td >same as <code>end(x)</code> </td>
|
<td >same as <code>end(x)</code> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr >
|
||||||
<a name="rend" ></a>
|
<a name="rend" ></a>
|
||||||
<td ><code >rend(x)</code></td>
|
<td ><code >rend(x)</code></td>
|
||||||
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
<td ><code >reverse_result_iterator_of<X>::type</code></td>
|
||||||
<td ><code >reverse_result_iterator_of<X>::type( begin(x)
|
<td ><code >reverse_result_iterator_of<X>::type( begin(x) )</code>
|
||||||
)</code> <td >same as <code>begin(x)</code></td>
|
<td >same as <code>begin(x)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
<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>
|
<p>
|
||||||
(C) Copyright Thorsten Ottosen 2003-2004
|
(C) Copyright Thorsten Ottosen 2003-2004
|
||||||
</p>
|
</p>
|
||||||
|
46
doc/faq.html
46
doc/faq.html
@ -29,6 +29,9 @@
|
|||||||
When it is possible to come up with one, the client might choose to construct a <code >std::pair<const_iterator,const_iterator></code>
|
When it is possible to come up with one, the client might choose to construct a <code >std::pair<const_iterator,const_iterator></code>
|
||||||
object.
|
object.
|
||||||
</p>
|
</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 >
|
<li >
|
||||||
<i>Why is there not supplied more types or more functions?</i>
|
<i>Why is there not supplied more types or more functions?</i>
|
||||||
<p >
|
<p >
|
||||||
@ -58,11 +61,13 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i>Should I use qualified syntax, for example
|
<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
|
instead of
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>using namespace boost;
|
<pre><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>;</span>
|
||||||
begin( r )</pre></blockquote>
|
<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
|
when calling functions in this library? If so, can I still rely on argument
|
||||||
dependent lookup (ADL) to kick in?</i>
|
dependent lookup (ADL) to kick in?</i>
|
||||||
<p>
|
<p>
|
||||||
@ -73,27 +78,30 @@ begin( r )</pre></blockquote>
|
|||||||
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
|
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
|
||||||
it is best explained by some code: <blockquote>
|
it is best explained by some code: <blockquote>
|
||||||
<pre>
|
<pre>
|
||||||
namespace boost
|
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||||
{
|
<span class=special>{
|
||||||
namespace range_detail
|
</span><span class=keyword>namespace </span><span class=identifier>range_detail
|
||||||
{
|
</span><span class=special>{
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
typename iterator_of<T>:type begin( T& r )
|
</span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>:</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </span><span class=special>)
|
||||||
{ /* normal implementation */ }
|
</span><span class=special>{ </span><span class=comment>/* normal implementation */ </span><span class=special>}
|
||||||
}
|
</span><span class=special>}
|
||||||
|
|
||||||
template< class T >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||||
typename iterator_of<T>::type begin( T& r )
|
</span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </span><span class=special>)
|
||||||
{
|
</span><span class=special>{
|
||||||
//
|
</span><span class=comment>//
|
||||||
// Create ADL hook
|
// Create ADL hook
|
||||||
//
|
//
|
||||||
using range_detail::begin;
|
</span><span class=keyword>using </span><span class=identifier>range_detail</span><span class=special>::</span><span class=identifier>begin</span><span class=special>;
|
||||||
return begin( r );
|
</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>
|
||||||
} </pre>
|
<span class=special>} </span>
|
||||||
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
Cool indeed!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
<h2 >History and Acknowledgement</h2><a name="History" ></a>
|
<h2 >History and Acknowledgement</h2><a name="History" ></a>
|
||||||
<p >
|
<p >
|
||||||
The library have been under way for a long time. Dietmar K<>hl originally
|
The library have been under way for a long time. Dietmar K<>hl originally
|
||||||
intended to submit an <code >array_traits<></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
|
had most of the functionality present now, but only for arrays and standard
|
||||||
containers.
|
containers.
|
||||||
</p>
|
</p>
|
||||||
@ -48,9 +48,10 @@ C++ standard: <blockquote>
|
|||||||
<p>
|
<p>
|
||||||
Special thanks goes to
|
Special thanks goes to
|
||||||
<ul>
|
<ul>
|
||||||
<li> Pavol Droba
|
<li> Pavol Droba for help with documentation and implementation
|
||||||
<li> Pavel Vozenilek
|
<li> Pavel Vozenilek for help with porting the library
|
||||||
<li> Jonathan Turkanis
|
<li> Jonathan Turkanis for help with documentation
|
||||||
|
<li> Hartmut Kaiser for being review manager
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
<hr>
|
<hr>
|
||||||
|
102
doc/intro.html
102
doc/intro.html
@ -18,16 +18,24 @@
|
|||||||
|
|
||||||
<h2>Introduction</h2>
|
<h2>Introduction</h2>
|
||||||
<p>
|
<p>
|
||||||
When writing generic code that works with Standard Library containers, one often
|
When writing generic code that works with standard library containers, one
|
||||||
finds it desirable to extend that code to work with other types that offer
|
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
|
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
|
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
|
works with containers, provided a suitable adapter is used. Likewise, null
|
||||||
terminated strings can be treated as containers of characters, if suitably
|
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
|
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.
|
||||||
</p>
|
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>
|
<!-- <p>
|
||||||
This library makes it possible to treat different types as if they have
|
This library makes it possible to treat different types as if they have
|
||||||
@ -62,59 +70,67 @@ arrays?) </li>
|
|||||||
):
|
):
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre >
|
<pre >
|
||||||
|
<span class=comment>
|
||||||
//
|
//
|
||||||
// example: extracting bounds in a generic algorithm
|
// example: extracting bounds in a generic algorithm
|
||||||
//
|
//
|
||||||
template< typename ForwardRange, typename T >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
inline typename boost::iterator_of< ForwardRange >::type
|
</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>< </span><span class=identifier>ForwardReadableRange </span><span class=special>>::</span><span class=identifier>type
|
||||||
find( ForwardRange& c, const T& value )
|
</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>ForwardReadableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value </span><span class=special>)
|
||||||
{
|
</span><span class=special>{
|
||||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
</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 >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
inline typename boost::const_iterator_of< ForwardRange >::type
|
</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>< </span><span class=identifier>ForwardReadableRange </span><span class=special>>::</span><span class=identifier>type
|
||||||
find( const ForwardRange& c, const T& value )
|
</span><span class=identifier>find</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardReadableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value </span><span class=special>)
|
||||||
{
|
</span><span class=special>{
|
||||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
</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
|
// replace first value and return its index
|
||||||
//
|
//
|
||||||
template< class ForwardRange, class T >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
inline typename boost::size_type_of< ForwardRange >::type
|
</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>< </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>>::</span><span class=identifier>type
|
||||||
my_generic_replace( ForwardRange& c, const T& value, const T& replacement )
|
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>replacement </span><span class=special>)
|
||||||
{
|
</span><span class=special>{
|
||||||
typename boost::iterator_of< ForwardRange >::type found = find( c, value );
|
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>iterator_of</span><span class=special>< </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>>::</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 ) )
|
</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>)
|
||||||
*found = replacement;
|
</span><span class=special>*</span><span class=identifier>found </span><span class=special>= </span><span class=identifier>replacement</span><span class=special>;
|
||||||
return std::distance( boost::begin( c ), found );
|
</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
|
// usage
|
||||||
//
|
//
|
||||||
const int N = 5;
|
</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>;
|
||||||
std::vector<int> my_vector;
|
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>> </span><span class=identifier>my_vector</span><span class=special>;
|
||||||
int values[] = { 1,2,3,4,5,6,7,8,9 };
|
</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>};
|
||||||
my_vector.assign( values, values + 9 );
|
</span>
|
||||||
typedef std::vector<int>::iterator iterator;
|
<span class=identifier>my_vector</span><span class=special>.</span><span
|
||||||
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
|
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>
|
||||||
boost::begin( my_vector ) + N );
|
</span><span class=keyword>typedef </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>>::</span><span class=identifier>iterator </span><span class=identifier>iterator</span><span class=special>;
|
||||||
char str_val[] = "a string";
|
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>> </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>),
|
||||||
char* str = str_val;
|
</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>"a string"</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>;
|
||||||
|
|
||||||
std::cout << my_generic_replace( my_vector, 4, 2 )
|
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special><< </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>)
|
||||||
<< my_generic_replace( my_view, 4, 2 )
|
</span><span class=special><< </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>)
|
||||||
<< my_generic_replace( str, 'a', 'b' );
|
</span><span class=special><< </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>
|
</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
By using the free-standing functions and metafunctions, the code automatically
|
By using the free-standing functions and <a
|
||||||
works for all the types supported by this library. Notice that we have to
|
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
|
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
|
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> ).
|
Forwarding Problem</a> ).
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
library. </p>
|
library. </p>
|
||||||
<p >
|
<p >
|
||||||
Notice that some compilers cannot do function template ordering properly. In
|
Notice that some compilers cannot do function template ordering properly. In
|
||||||
that case one must rely of <code >result_iterator_of<></code> and a
|
that case one must rely of <code >result_iterator_of</code> and a
|
||||||
single function definition instead of
|
single function definition instead of
|
||||||
overloaded versions for const and non-const arguments.
|
overloaded versions for const and non-const arguments.
|
||||||
|
|
||||||
|
@ -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>
|
iterators support. See also <a href="style.html">terminology and style guidelines.</a>
|
||||||
for more information about naming of ranges.</p>
|
for more information about naming of ranges.</p>
|
||||||
|
|
||||||
<p>
|
<p> The concepts described below specifies associated types as
|
||||||
|
<a href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and all
|
||||||
</p>
|
functions as free-standing functions to allow for a layer of indirection. </p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<a name="single_pass_range">
|
<a name="single_pass_range">
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
Notice how we have used the categories from the <a href=../../iterator/doc/new-iter-concepts.html>new
|
Notice how we have used the categories from the <a href=../../iterator/doc/new-iter-concepts.html>new
|
||||||
style iterators</a>.
|
style iterators</a>.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Notice that an iterator (and therefore an range) has one <i>traversal</i>
|
Notice that an iterator (and therefore an range) has one <i>traversal</i>
|
||||||
@ -74,25 +74,36 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
As an example, consider how we specify the interface of <code>std::sort()</code>.
|
It might, however, be reasonable to specify only one category if the other
|
||||||
The iterator-based version looks like this:
|
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>
|
<pre>
|
||||||
template< class RandomAccessTraversalReadableWritableIterator >
|
<span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=special>>
|
||||||
void sort( RandomAccessTraversalReadableWritableIterator first,
|
</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>,
|
||||||
RandomAccessTraversalReadableWritableIterator last );
|
</span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=identifier>last </span><span class=special>);</span>
|
||||||
</pre>
|
</pre>
|
||||||
For ranges the interface becomes
|
For ranges the interface becomes
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
template< class RandomAccessReadableWritableRange >
|
<span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>RandomAccessReadableWritableRange </span><span class=special>>
|
||||||
void sort( RandomAccessReadableWritableRange& r );
|
</span><span class=keyword>void </span><span class=identifier>sort</span><span class=special>( </span><span class=identifier>RandomAccessReadableWritableRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
<p>
|
||||||
(C) Copyright Thorsten Ottosen 2003-2004
|
(C) Copyright Thorsten Ottosen 2003-2004
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
<li>
|
<li>
|
||||||
Class <a href=#iter_range><code>iterator_range</code></a>
|
Class <a href=#iter_range><code>iterator_range</code></a>
|
||||||
<li>
|
<li>
|
||||||
Class <a href=#sub_range><code>sub_range</code></a>
|
Class <a href=#sub_range><code>sub_range</code></a>
|
||||||
</ul>
|
</ul>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -37,133 +37,157 @@
|
|||||||
Traversal Iterator</a> and should be used whenever fairly general code is needed.
|
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
|
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
|
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>
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<a name=iter_range></a> <h1>Class <code>iterator_range</code></h1>
|
<a name=iter_range></a> <h1>Class <code>iterator_range</code></h1>
|
||||||
<p>
|
<p>
|
||||||
The intention of the <code>iterator_range</code> class is to encapsulate two
|
The intention of the <code>iterator_range</code> class is to encapsulate two
|
||||||
iterators so they fulfill the <a
|
iterators so they fulfill the <a
|
||||||
href="range.htm#forward_range">Forward Range</a> concept. A few other functions
|
href="range.htm#forward_range">Forward Range</a> concept. A few other functions
|
||||||
are also provided for convenience.
|
are also provided for convenience.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If the template argument is not a model of Forward Traversal Iterator, one
|
If the template argument is not a model of Forward Traversal Iterator, one can
|
||||||
can still use a subset of the interface. In particular, <code>size()</code>
|
still use a subset of the interface. In particular, <code>size()</code> requires
|
||||||
requires Forward Traversal Iterators whereas <code>empty()</code> only
|
Forward Traversal Iterators whereas <code>empty()</code> only requires Single
|
||||||
requires Single Pass Iterators.
|
Pass Iterators.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Synopsis</h3>
|
<h3>Synopsis</h3>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
namespace boost
|
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||||
{
|
<span class=special>{
|
||||||
template< class ForwardTraversalIterator >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||||
class iterator_range
|
</span><span class=keyword>class </span><span class=identifier>iterator_range
|
||||||
{
|
</span><span class=special>{
|
||||||
iterator_range(); // not implemented
|
</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>;
|
||||||
public: // Forward Range types
|
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>difference_type</span><span class=special>;
|
||||||
typedef ... value_type;
|
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>size_type</span><span class=special>;
|
||||||
typedef ... difference_type;
|
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>iterator</span><span class=special>;
|
||||||
typedef ... size_type;
|
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>const_iterator</span><span class=special>;
|
||||||
typedef ForwardTraversalIterator iterator;
|
|
||||||
typedef ForwardTraversalIterator const_iterator;
|
|
||||||
|
|
||||||
public: // construction, assignment
|
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
|
||||||
template< class ForwardTraversalIterator2 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>>
|
||||||
iterator_range( ForwardTraversalIterator2 Begin, ForwardTraversalIterator2 End );
|
</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>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range( ForwardRange& r );
|
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range( const ForwardRange& r );
|
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range& operator=( ForwardRange& r );
|
</span><span class=identifier>iterator_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range& operator=( const ForwardRange& r );
|
</span><span class=identifier>iterator_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
public: // Forward Range functions
|
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// Forward Range functions
|
||||||
iterator begin() const;
|
</span><span class=identifier>iterator </span><span class=identifier>begin</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||||
iterator end() const;
|
</span><span class=identifier>iterator </span><span class=identifier>end</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||||
size_type size() const;
|
</span><span class=identifier>size_type </span><span class=identifier>size</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||||
bool empty() const;
|
</span><span class=keyword>bool </span><span class=identifier>empty</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||||
|
|
||||||
public: // convenience
|
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// convenience
|
||||||
operator unspecified_bool_type() const;
|
</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>};
|
||||||
|
|
||||||
// stream output
|
</span><span class=comment>// stream output
|
||||||
template< class ForwardTraversalIterator, class T, class Traits >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
std::basic_ostream<T,Traits>& operator<<( std::basic_ostream<T,Traits>& Os,
|
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>>&
|
||||||
const iterator_range<ForwardTraversalIterator>& r );
|
</span><span class=keyword>operator</span><span class=special><<( </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>>& </span><span class=identifier>Os</span><span class=special>,
|
||||||
|
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
// comparison
|
</span><span class=comment>// comparison
|
||||||
template< class ForwardTraversalIterator >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
bool operator==( const iterator_range<ForwardTraversalIterator>& l, const iterator_range<ForwardTraversalIterator>& r );
|
</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><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||||
|
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardTraversalIterator >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
bool operator!=( const iterator_range<ForwardTraversalIterator>& l, const iterator_range<ForwardTraversalIterator>& r );
|
</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><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||||
|
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
// external construction
|
</span><span class=comment>// external construction
|
||||||
template< class ForwardTraversalIterator >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||||
iterator_range< ForwardTraversalIterator >
|
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||||
make_iterator_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
|
</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>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range< typename iterator_of<ForwardRange>::type >
|
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||||
make_iterator_range( ForwardRange& r );
|
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
iterator_range< typename const_iterator_of<ForwardRange>::type >
|
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||||
make_iterator_range( const ForwardRange& r );
|
</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>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
// convenience
|
</span><span class=comment>// convenience
|
||||||
template< class Sequence, class ForwardRange >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
Sequence copy_range( const ForwardRange& r );
|
</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>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class Sequence, class ForwardRange, class Func >
|
</span><span class=keyword>template</span><span class=special>< </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>>
|
||||||
Sequence transform_range( const ForwardRange& r, Func func );
|
</span><span class=identifier>Sequence </span><a
|
||||||
|
href="#transform_range"><span
|
||||||
} // namespace 'boost'
|
class=identifier>transform_range</span></a><span class=special>( </span><span
|
||||||
|
class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </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>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
It is worth noticing that the templated constructors and assignment operators
|
If an instance of
|
||||||
allow conversion from <code>iterator_range<iterator></code> to
|
|
||||||
<code>iterator_range<const_iterator></code>. If an instance of
|
|
||||||
<code>iterator_range</code> is constructed by a client with two iterators, the
|
<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
|
client must ensure that the two iterators delimit a valid closed-open range
|
||||||
<code>[begin,end)</code>.
|
<code>[begin,end)</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is worth noticing that the templated constructors and assignment operators
|
||||||
|
allow conversion from <code>iterator_range<iterator></code> to
|
||||||
|
<code>iterator_range<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>
|
<h3>Details member functions</h3>
|
||||||
|
|
||||||
<code>operator unspecified_bool_type() const; </code>
|
<a name="unspecified_bool"></a>
|
||||||
|
<code>operator unspecified_bool_type() const; </code>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
Returns <code>!empty().</code>
|
Returns <code>!empty().</code>
|
||||||
|
|
||||||
<!--
|
|
||||||
<b>Example</b> <code> iterator_range<const char*> r( "a string" ); if( r )
|
<!--
|
||||||
do_something();</code>-->
|
<b>Example</b> <code> iterator_range<const char*> r( "a string" ); if( r )
|
||||||
|
do_something();</code>-->
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<h3>Details functions</h3>
|
<h3>Details functions</h3>
|
||||||
|
|
||||||
|
<a name="copy_range"></a>
|
||||||
<code>Sequence copy_range( const ForwardRange& r );</code>
|
<code>Sequence copy_range( const ForwardRange& r );</code>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
Constructs a new sequence of the specified type from the elements
|
Constructs a new sequence of the specified type from the elements
|
||||||
in the given range.
|
in the given range.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
<a name="transform_range"></a>
|
||||||
<code>Sequence transform_range( const ForwardRange& r, Func func );</code>
|
<code>Sequence transform_range( const ForwardRange& r, Func func );</code>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
Constructs a new sequence from the elements in the range,
|
Constructs a new sequence from the elements in the range,
|
||||||
transformed by a function.
|
transformed by a function.
|
||||||
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
@ -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.
|
from the <a href="#iter_range"><code>iterator_range</code></a> class.
|
||||||
The <code>sub_range</code> class is often easier to use because
|
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>
|
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>
|
<h3>Synopsis</h3>
|
||||||
|
|
||||||
<pre>
|
<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>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||||
|
</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>< </span><span class=keyword>typename </span><span class=identifier>result_iterator_of</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||||
|
</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><</span><span class=identifier>ForwardRange</span><span
|
||||||
|
class=special>>::</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><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=identifier>const_iterator</span><span class=special>;</span>
|
||||||
|
|
||||||
template< class ForwardRange >
|
<span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
|
||||||
class sub_range : public iterator_range< typename result_iterator_of<ForwardRange>::type >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||||
{
|
</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>);
|
||||||
public: // construction, assignment
|
|
||||||
template< class ForwardTraversalIterator >
|
|
||||||
sub_range( ForwardTraversalIterator Begin, ForwardTraversalIterator End );
|
|
||||||
|
|
||||||
template< class ForwardRange2 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||||
sub_range( ForwardRange2& r );
|
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardRange2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange2 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||||
sub_range( const Range2& r );
|
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>Range2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange2 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||||
sub_range& operator=( ForwardRange2& r );
|
</span><span class=identifier>sub_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||||
|
|
||||||
template< class ForwardRange2 >
|
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||||
sub_range& operator=( const ForwardRange2& r );
|
</span><span class=identifier>sub_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange2</span><span class=special>& </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:
|
<span class=keyword>public</span><span class=special>:
|
||||||
// rest of interface inherited from iterator_range
|
</span><span class=comment>// rest of interface inherited from iterator_range
|
||||||
};
|
</span><span class=special>};
|
||||||
|
</span>
|
||||||
} // namespace 'boost'
|
<span class=special>} </span><span class=comment>// namespace 'boost'</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<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>
|
<pre>
|
||||||
typedef sub_range<std::string> sub_string;
|
<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>"hello"</span><span class=special>);
|
||||||
std::string s = "something";
|
</span><span class=identifier>iterator_range</span><span class=special><</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>> </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>"ll" </span><span class=special>);
|
||||||
sub_string ss( s );
|
</span><span class=identifier>sub_range</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>> </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>"ll" </span><span class=special>);</span>
|
||||||
sub_string ss2( begin( s ), begin( s ) + 2 );</pre>
|
</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
<p>
|
||||||
@ -236,6 +279,7 @@ namespace boost
|
|||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ namespace boost {
|
|||||||
template<typename IteratorT>
|
template<typename IteratorT>
|
||||||
class iterator_range
|
class iterator_range
|
||||||
{
|
{
|
||||||
iterator_range(); // not implemented
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! this type
|
//! this type
|
||||||
typedef iterator_range<IteratorT> type;
|
typedef iterator_range<IteratorT> type;
|
||||||
@ -185,9 +183,9 @@ namespace boost {
|
|||||||
/*!
|
/*!
|
||||||
Compare operands for equality
|
Compare operands for equality
|
||||||
*/
|
*/
|
||||||
template< class IteratorT >
|
template< class IteratorT, class IteratorT2 >
|
||||||
inline bool operator==( const iterator_range<IteratorT>& l,
|
inline bool operator==( const iterator_range<IteratorT>& l,
|
||||||
const iterator_range<IteratorT>& r )
|
const iterator_range<IteratorT2>& r )
|
||||||
{
|
{
|
||||||
return ! (l != r);
|
return ! (l != r);
|
||||||
}
|
}
|
||||||
@ -196,9 +194,9 @@ namespace boost {
|
|||||||
/*!
|
/*!
|
||||||
Compare operands for non-equality
|
Compare operands for non-equality
|
||||||
*/
|
*/
|
||||||
template< class IteratorT >
|
template< class IteratorT, class IteratorT2 >
|
||||||
inline bool operator!=( const iterator_range<IteratorT>& l,
|
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();
|
return l.begin() != r.begin() || l.end() != r.end();
|
||||||
}
|
}
|
||||||
|
@ -23,17 +23,15 @@ namespace boost
|
|||||||
template< class ForwardRange >
|
template< class ForwardRange >
|
||||||
class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME result_iterator_of<ForwardRange>::type >
|
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 BOOST_DEDUCED_TYPENAME result_iterator_of<ForwardRange>::type iterator_t;
|
||||||
typedef iterator_range< iterator_t > base;
|
typedef iterator_range< iterator_t > base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using base::iterator;
|
using BOOST_DEDUCED_TYPENAME base::value_type;
|
||||||
using base::const_iterator;
|
using BOOST_DEDUCED_TYPENAME base::iterator;
|
||||||
using base::value_type;
|
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 difference_type_of<ForwardRange>::type difference_type;
|
||||||
typedef BOOST_DEDUCED_TYPENAME size_type_of<ForwardRange>::type size_type;
|
typedef BOOST_DEDUCED_TYPENAME size_type_of<ForwardRange>::type size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template< class ForwardRange2 >
|
template< class ForwardRange2 >
|
||||||
@ -63,10 +61,13 @@ namespace boost
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type size() const
|
public:
|
||||||
{
|
|
||||||
return base::size();
|
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() ); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include <boost/range/functions.hpp >
|
#include <boost/range/functions.hpp >
|
||||||
#include <boost/range/metafunctions.hpp>
|
#include <boost/range/metafunctions.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -24,7 +26,6 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
//
|
//
|
||||||
// example: extrating bounds in a generic algorithm
|
// example: extrating bounds in a generic algorithm
|
||||||
//
|
//
|
||||||
@ -58,12 +59,12 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
void check_algorithm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// usage
|
// usage
|
||||||
//
|
//
|
||||||
const int N = 5;
|
const unsigned N = 5;
|
||||||
std::vector<int> my_vector;
|
std::vector<int> my_vector;
|
||||||
int values[] = { 1,2,3,4,5,6,7,8,9 };
|
int values[] = { 1,2,3,4,5,6,7,8,9 };
|
||||||
my_vector.assign( values, values + 9 );
|
my_vector.assign( values, values + 9 );
|
||||||
@ -73,8 +74,24 @@ int main()
|
|||||||
char str_val[] = "a string";
|
char str_val[] = "a string";
|
||||||
char* str = str_val;
|
char* str = str_val;
|
||||||
|
|
||||||
std::cout << my_generic_replace( my_vector, 4, 2 )
|
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3u );
|
||||||
<< my_generic_replace( my_view, 4, 2 )
|
BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
|
||||||
<< my_generic_replace( str, 'a', 'b' );
|
BOOST_CHECK_EQUAL( my_generic_replace( str, 'a', 'b' ), 0u );
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,11 +60,13 @@ void check_iterator_range()
|
|||||||
typedef sub_range<const string> csrange;
|
typedef sub_range<const string> csrange;
|
||||||
srange s = r;
|
srange s = r;
|
||||||
BOOST_CHECK( r == r );
|
BOOST_CHECK( r == r );
|
||||||
|
BOOST_CHECK( s == r );
|
||||||
s = make_iterator_range( str );
|
s = make_iterator_range( str );
|
||||||
csrange s2 = r;
|
csrange s2 = r;
|
||||||
s2 = r2;
|
s2 = r2;
|
||||||
s2 = make_iterator_range( cstr );
|
s2 = make_iterator_range( cstr );
|
||||||
BOOST_CHECK( r2 == r2 );
|
BOOST_CHECK( r2 == r2 );
|
||||||
|
BOOST_CHECK( s2 != r2 );
|
||||||
s2 = make_iterator_range( str );
|
s2 = make_iterator_range( str );
|
||||||
BOOST_CHECK( !(s != s) );
|
BOOST_CHECK( !(s != s) );
|
||||||
|
|
||||||
@ -88,7 +90,10 @@ void check_iterator_range()
|
|||||||
|
|
||||||
string res = copy_range<string>( r );
|
string res = copy_range<string>( r );
|
||||||
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
|
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();
|
r.empty();
|
||||||
s.empty();
|
s.empty();
|
||||||
r.size();
|
r.size();
|
||||||
|
Reference in New Issue
Block a user