merge from 1.33.1

[SVN r31968]
This commit is contained in:
Thorsten Jørgen Ottosen
2005-12-09 22:22:32 +00:00
parent a2b6c3f5ec
commit c08103b1c5
13 changed files with 1005 additions and 466 deletions

View File

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

141
doc/example.cpp Normal file
View File

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

View File

@ -125,9 +125,9 @@ class=identifier>assign</span><span class=special>( </span><span class=identifie
</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=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=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=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=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_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=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>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>
<span class=comment>// prints '3', '5' and '0' </span> <span class=comment>// prints '3', '5' and '0' </span>
</pre> </pre>

View File

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

View File

@ -15,6 +15,7 @@
# pragma once # pragma once
#endif #endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@ -46,7 +47,8 @@ namespace range_detail
} }
template< typename C > template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_begin( C& c ) boost_range_begin( C& c )
{ {
return c.begin(); return c.begin();
@ -140,7 +142,8 @@ namespace range_detail
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r ) inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type begin( T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \ !BOOST_WORKAROUND(__GNUC__, < 3) \

View File

@ -16,12 +16,25 @@
#endif #endif
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/const_iterator.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/difference_type.hpp>
#else
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_difference
{
typedef BOOST_DEDUCED_TYPENAME iterator_difference<
BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type >::type
type;
};
}
//#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//#include <boost/range/detail/difference_type.hpp>
//#else
/*
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
@ -127,5 +140,6 @@ namespace boost
} // namespace boost } // namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
*/
#endif #endif

View File

@ -15,6 +15,7 @@
# pragma once # pragma once
#endif #endif
#include <boost/type_traits/remove_const.hpp>
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
@ -47,7 +48,8 @@ namespace range_detail
} }
template< typename C > template< typename C >
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<C>::type >::type
boost_range_end( C& c ) boost_range_end( C& c )
{ {
return c.end(); return c.end();
@ -139,7 +141,8 @@ namespace range_detail
#endif #endif
template< class T > template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r ) inline BOOST_DEDUCED_TYPENAME range_iterator<
typename remove_const<T>::type >::type end( T& r )
{ {
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \ #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(__GNUC__, < 3) \ !BOOST_WORKAROUND(__GNUC__, < 3) \

View File

@ -35,10 +35,12 @@ rbegin( C& c )
#else #else
template< class C > template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rbegin( C& c ) rbegin( C& c )
{ {
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type; iter_type;
return iter_type( end( c ) ); return iter_type( end( c ) );
} }

View File

@ -35,10 +35,12 @@ rend( C& c )
#else #else
template< class C > template< class C >
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
rend( C& c ) rend( C& c )
{ {
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<
typename remove_const<C>::type >::type
iter_type; iter_type;
return iter_type( begin( c ) ); return iter_type( begin( c ) );
} }

View File

@ -16,6 +16,54 @@
#endif #endif
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
/*
#include <boost/range/difference_type.hpp>
namespace boost
{
namespace range_detail
{
template< class T >
struct add_unsigned;
template<>
struct add_unsigned<short>
{
typedef unsigned short type;
};
template<>
struct add_unsigned<int>
{
typedef unsigned int type;
};
template<>
struct add_unsigned<long>
{
typedef unsigned long type;
};
#ifdef BOOST_HAS_LONG_LONG
template<>
struct add_unsigned<long long>
{
typedef unsigned long long type;
};
#endif
}
template< class T >
struct range_size
{
typedef BOOST_DEDUCED_TYPENAME range_detail::add_unsigned<
BOOST_DEDUCED_TYPENAME range_difference<T>::type >::type
type;
};
}
*/
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/size_type.hpp> #include <boost/range/detail/size_type.hpp>
@ -124,4 +172,5 @@ namespace boost
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif #endif

View File

@ -16,12 +16,26 @@
#endif #endif
#include <boost/range/config.hpp> #include <boost/range/config.hpp>
#include <boost/range/iterator.hpp>
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/range/detail/value_type.hpp> #include <boost/range/detail/value_type.hpp>
#else #else
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
namespace boost
{
template< class T >
struct range_value
{
typedef BOOST_DEDUCED_TYPENAME iterator_value<
BOOST_DEDUCED_TYPENAME range_iterator<T>::type >::type
type;
};
}
/*
#include <cstddef> #include <cstddef>
#include <utility> #include <utility>
@ -126,7 +140,7 @@ namespace boost
}; };
} // namespace boost } // namespace boost
*/
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#endif #endif

View File

@ -35,6 +35,7 @@ test-suite range :
[ range-test algorithm_example ] [ range-test algorithm_example ]
[ range-test reversible_range ] [ range-test reversible_range ]
[ range-test const_ranges ] [ range-test const_ranges ]
[ range-test extension_mechanism ]
# [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ] # [ range-test mfc : <include>$(VC71_ROOT)/atlmfc/include ]
; ;

112
test/extension_mechanism.cpp Executable file
View File

@ -0,0 +1,112 @@
// 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/
//
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# pragma warn -8091 // supress warning in Boost.Test
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
//
// Generic range algorithm
//
template< class Rng >
typename boost::range_result_iterator<Rng>::type foo_algo( Rng& r )
{
//
// This will only compile for Rng = UDT if the qualified calls
// find boost_range_XXX via ADL.
//
return boost::size(r) == 0u ? boost::begin(r) : boost::end(r);
}
namespace Foo
{
//
// Our sample UDT
//
struct X
{
typedef std::vector<int> data_t;
typedef data_t::iterator iterator;
typedef data_t::const_iterator const_iterator;
typedef data_t::size_type size_type;
data_t vec;
void push_back( int i )
{ vec.push_back(i); }
};
//
// The required functions. No type-traits need
// to be defined because X defines the proper set of
// nested types.
//
inline X::iterator boost_range_begin( X& x )
{
return x.vec.begin();
}
inline X::const_iterator boost_range_begin( const X& x )
{
return x.vec.begin();
}
inline X::iterator boost_range_end( X& x )
{
return x.vec.end();
}
inline X::const_iterator boost_range_end( const X& x )
{
return x.vec.end();
}
inline X::size_type boost_range_size( const X& x )
{
return x.vec.size();
}
}
void check_extension()
{
Foo::X x;
x.push_back(3);
const Foo::X x2;
foo_algo( x );
foo_algo( x2 );
}
using boost::unit_test::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_extension ) );
return test;
}