forked from boostorg/range
merge from 1.33.1
[SVN r31968]
This commit is contained in:
@ -1,78 +1,67 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Boost.Range Range Implementation </title>
|
<title>Boost.Range 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
|
||||||
Boost.Range </h1></td>
|
</h1>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<h2>Synopsis and Reference
|
||||||
<h2>Synopsis and Reference </h2>
|
</h2>
|
||||||
|
<ul>
|
||||||
<ul >
|
|
||||||
<li>
|
<li>
|
||||||
<a href="#overview">Overview</a>
|
<a href="#overview">Overview</a>
|
||||||
<li >
|
|
||||||
<a href="#Synopsis" >Synopsis</a>
|
|
||||||
</li>
|
|
||||||
<li >
|
|
||||||
<a href="#Semantics" >Semantics</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href="#minimal_interface">Extending the library</a>
|
<a href="#Synopsis">Synopsis</a>
|
||||||
|
<li>
|
||||||
|
<a href="#Semantics">Semantics</a>
|
||||||
|
<li>
|
||||||
|
<a href="#minimal_interface">Extending the library</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<hr size="1" >
|
<hr size="1">
|
||||||
|
|
||||||
<a name="overview"></a>
|
<a name="overview"></a>
|
||||||
<h3>Overview</h3>
|
<h3>Overview</h3>
|
||||||
<p>
|
<p>
|
||||||
Four types of objects are currently supported by the library:
|
Four types of objects are currently supported by the library:
|
||||||
<ul >
|
<ul>
|
||||||
<li >
|
<li>
|
||||||
standard-like containers
|
standard-like containers
|
||||||
</li>
|
<li>
|
||||||
<li >
|
<code>std::pair<iterator,iterator></code>
|
||||||
<code >std::pair<iterator,iterator></code>
|
<li>
|
||||||
</li>
|
null terminated strings (this includes <code>char[]</code>,<code>wchar_t[]</code>,
|
||||||
<li >
|
<code>char*</code>, and <code>wchar_t*</code>)
|
||||||
null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,
|
|
||||||
<code >char*</code>, and <code >wchar_t*</code>)
|
|
||||||
<p>
|
<p>
|
||||||
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
|
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
|
||||||
disappear in the next Boost release (1.34). </i>
|
disappear in the next Boost release (1.34). </i>
|
||||||
</p>
|
</p>
|
||||||
|
<li>
|
||||||
</li>
|
|
||||||
<li >
|
|
||||||
built-in arrays
|
built-in arrays
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Even though the behavior of the primary templates are exactly such that
|
||||||
Even though the behavior of the primary templates are exactly such that standard
|
standard containers will be supported by default, the requirements are much
|
||||||
containers will be supported by default, the requirements are much lower than
|
lower than the standard container requirements. For example, the utility class <a href="utility_class.html#iter_range">
|
||||||
the standard container requirements. For example, the utility class <a
|
<code>iterator_range</code></a> implements the <a href="#minimal_interface">minimal
|
||||||
href="utility_class.html#iter_range"><code>iterator_range</code></a> implements
|
interface</a> required to make the class a <a href="range.html#forward_range">Forward
|
||||||
the <a href="#minimal_interface">minimal interface</a> required to make the
|
Range</a>
|
||||||
class a <a href="range.html#forward_range">Forward Range</a>.
|
.
|
||||||
</p>
|
<P></P>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Please also see <a href="range.html">Range concepts</a> for more details.
|
Please also see <a href="range.html">Range concepts</a> for more details.
|
||||||
</p>
|
</p>
|
||||||
|
<a name="Synopsis"></a>
|
||||||
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
|
<h3>Synopsis</h3>
|
||||||
|
<p>
|
||||||
<p >
|
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||||
<span class=special>{
|
<span class=special>{
|
||||||
@ -207,33 +196,34 @@ class=identifier>T</span><span class=special>& </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<iterator,iterator></code>
|
<td>denotes <code>std::pair<iterator,iterator></code></td>
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>A[sz]</code>
|
<td><code>A[sz]</code>
|
||||||
<td><code>a</code>
|
<td><code>a</code>
|
||||||
@ -242,250 +232,282 @@ class=identifier>T</span><span class=special>& </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<X>::type</code></td>
|
<td><code>range_value<X>::type</code></td>
|
||||||
<td ><code >T::value_type</code><br>
|
<td><code>T::value_type</code><br>
|
||||||
<code >boost::iterator_value<P::first_type>::type</code><br>
|
<code>boost::iterator_value<P::first_type>::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>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="range_iterator" ></a>
|
<a name="range_iterator"></a>
|
||||||
<td ><code >range_iterator<X>::type</code></td>
|
<td><code>range_iterator<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="range_const_iterator" ></a>
|
<a name="range_const_iterator"></a>
|
||||||
<td ><code >range_const_iterator<X>::type</code></td>
|
<td><code>range_const_iterator<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>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="range_difference" ></a>
|
<a name="range_difference"></a>
|
||||||
<td ><code >range_difference<X>::type</code></td>
|
<td><code>range_difference<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>
|
||||||
<a name="range_size" ></a>
|
<a name="range_size"></a>
|
||||||
<td ><code >range_size<X>::type</code></td>
|
<td><code>range_size<X>::type</code></td>
|
||||||
<td ><code >T::size_type</code><br>
|
<td><code>T::size_type</code><br>
|
||||||
<code >std::size_t</code><br>
|
<code>std::size_t</code><br>
|
||||||
<code >std::size_t</code><br>
|
<code>std::size_t</code><br>
|
||||||
<code >std::size_t</code><br>
|
<code>std::size_t</code><br>
|
||||||
<td >compile time</td>
|
<td>compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="range_result_iterator" ></a>
|
<a name="range_result_iterator"></a>
|
||||||
<td ><code >range_result_iterator<X>::type</code></td>
|
<td><code>range_result_iterator<X>::type</code></td>
|
||||||
<td ><code >range_const_iterator<X>::type</code> if <code
|
<td><code>range_const_iterator<X>::type</code> if <code>X</code> is <code>const</code>
|
||||||
>X</code> is <code >const</code> <br>
|
|
||||||
<code >range_iterator<X>::type</code> otherwise </td>
|
|
||||||
<td >compile time</td>
|
|
||||||
</tr>
|
|
||||||
<tr >
|
|
||||||
<a name="range_reverse_iterator" ></a>
|
|
||||||
<td ><code >range_reverse_iterator<X>::type</code></td>
|
|
||||||
<td ><code >boost::reverse_iterator< typename range_iterator<T>::type ></code><br>
|
|
||||||
<td >compile time</td>
|
|
||||||
</tr>
|
|
||||||
<tr >
|
|
||||||
<a name="range_const_reverse_iterator" ></a>
|
|
||||||
<td ><code >range_const_reverse_iterator<X>::type</code></td>
|
|
||||||
<td ><code >boost::reverse_iterator< typename range_const_iterator<T>::type ></code>
|
|
||||||
<br>
|
<br>
|
||||||
<td >compile time</td>
|
<code>range_iterator<X>::type</code> otherwise
|
||||||
|
</td>
|
||||||
|
<td>compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="range_reverse_result_iterator" ></a>
|
<a name="range_reverse_iterator"></a>
|
||||||
<td ><code >range_reverse_result_iterator<X>::type</code></td>
|
<td><code>range_reverse_iterator<X>::type</code></td>
|
||||||
<td ><code >boost::reverse_iterator< typename range_result_iterator<T>::type
|
<td><code>boost::reverse_iterator< typename range_iterator<T>::type ></code><br>
|
||||||
></code>
|
<td>compile time</td>
|
||||||
<td >compile time</td>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<a name="range_const_reverse_iterator"></a>
|
||||||
|
<td><code>range_const_reverse_iterator<X>::type</code></td>
|
||||||
|
<td><code>boost::reverse_iterator< typename range_const_iterator<T>::type ></code>
|
||||||
|
<br>
|
||||||
|
<td>compile time</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<a name="range_reverse_result_iterator"></a>
|
||||||
|
<td><code>range_reverse_result_iterator<X>::type</code></td>
|
||||||
|
<td><code>boost::reverse_iterator< typename range_result_iterator<T>::type
|
||||||
|
></code>
|
||||||
|
<td>compile time</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
The special metafunctions <code>range_result_iterator</code> and <code>range_reverse_result_iterator</code>
|
The special metafunctions <code>range_result_iterator</code> and <code>range_reverse_result_iterator</code>
|
||||||
are not part of any Range concept, but they are very useful when implementing
|
are not part of any Range concept, but they are very useful when implementing
|
||||||
certain Range classes like <a
|
certain Range classes like <a href="utility_class.html#sub_range"><code>sub_range</code></a>
|
||||||
href="utility_class.html#sub_range"><code>sub_range</code></a> because of their
|
because of their ability to select iterators based on constness.
|
||||||
ability to select iterators based on constness.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>Functions</h4>
|
<h4>Functions</h4>
|
||||||
<p>
|
<p>
|
||||||
<table border="1" cellpadding="5" >
|
<table border="1" cellpadding="5">
|
||||||
<tr >
|
<tr>
|
||||||
<th >Expression</th>
|
<th>
|
||||||
<th >Return type</th>
|
Expression</th>
|
||||||
<th >Returns</th>
|
<th>
|
||||||
<th >Complexity</th>
|
Return type</th>
|
||||||
|
<th>
|
||||||
|
Returns</th>
|
||||||
|
<th>
|
||||||
|
Complexity</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="begin" ></a>
|
<a name="begin"></a>
|
||||||
<td ><code >begin(x)</code></td>
|
<td><code>begin(x)</code></td>
|
||||||
<td ><code >range_result_iterator<X>::type</code></td>
|
<td><code>range_result_iterator<X>::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<T><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>
|
||||||
<td >constant time</td>
|
<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>
|
||||||
</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<X>::type</code></td>
|
<td><code>range_result_iterator<X>::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<T><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<X>::length( s )</code> if <code >X</code> is <code >Char*</code>
|
<code>s + std::char_traits<X>::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>
|
||||||
<a name="empty" ></a>
|
<a name="empty"></a>
|
||||||
<td ><code >empty(x)</code></td>
|
<td><code>empty(x)</code></td>
|
||||||
<td ><code >bool</code></td>
|
<td><code>bool</code></td>
|
||||||
<td ><code >begin(x) == end( x )</code><br>
|
<td><code>begin(x) == end( x )</code><br>
|
||||||
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
<td>linear if <code>X</code> is <code>Char*</code>
|
||||||
|
<br>
|
||||||
constant time otherwise<br>
|
constant time otherwise<br>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="size" ></a>
|
<a name="size"></a>
|
||||||
<td ><code >size(x)</code></td>
|
<td><code>size(x)</code></td>
|
||||||
<td ><code >range_size<X>::type</code></td>
|
<td><code>range_size<X>::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<T><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<X>::type</code></td>
|
<td><code>range_reverse_result_iterator<X>::type</code></td>
|
||||||
<td ><code >range_reverse_result_iterator<X>::type( end(x) )</code> <br>
|
<td><code>range_reverse_result_iterator<X>::type( end(x) )</code>
|
||||||
<td >same as <code>end(x)</code> </td>
|
<br>
|
||||||
|
<td>same as <code>end(x)</code>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="rend" ></a>
|
<a name="rend"></a>
|
||||||
<td ><code >rend(x)</code></td>
|
<td><code>rend(x)</code></td>
|
||||||
<td ><code >range_reverse_result_iterator<X>::type</code></td>
|
<td><code>range_reverse_result_iterator<X>::type</code></td>
|
||||||
<td ><code >range_reverse_result_iterator<X>::type( begin(x) )</code>
|
<td><code>range_reverse_result_iterator<X>::type( begin(x) )</code>
|
||||||
<td >same as <code>begin(x)</code></td>
|
<td>same as <code>begin(x)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="const_begin" ></a>
|
<a name="const_begin"></a>
|
||||||
<td ><code >const_begin(x)</code></td>
|
<td><code>const_begin(x)</code></td>
|
||||||
<td ><code >range_const_iterator<X>::type</code></td>
|
<td><code>range_const_iterator<X>::type</code></td>
|
||||||
<td ><code >range_const_iterator<X>::type( begin(x) )</code>
|
<td><code>range_const_iterator<X>::type( begin(x) )</code>
|
||||||
<br> <td >same as <code>begin(x)</code> </td>
|
<br>
|
||||||
|
<td>same as <code>begin(x)</code>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="const_end" ></a>
|
<a name="const_end"></a>
|
||||||
<td ><code >const_end(x)</code></td>
|
<td><code>const_end(x)</code></td>
|
||||||
<td ><code >range_const_iterator<X>::type</code></td>
|
<td><code>range_const_iterator<X>::type</code></td>
|
||||||
<td ><code >range_const_iterator<X>::type( end(x) )</code>
|
<td><code>range_const_iterator<X>::type( end(x) )</code>
|
||||||
<td >same as <code>end(x)</code></td>
|
<td>same as <code>end(x)</code></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="const_rbegin" ></a>
|
<a name="const_rbegin"></a>
|
||||||
<td ><code >const_rbegin(x)</code></td>
|
<td><code>const_rbegin(x)</code></td>
|
||||||
<td ><code >range_const_reverse_iterator<X>::type</code></td>
|
<td><code>range_const_reverse_iterator<X>::type</code></td>
|
||||||
<td ><code >range_const_reverse_iterator<X>::type( rbegin(x) )</code>
|
<td><code>range_const_reverse_iterator<X>::type( rbegin(x) )</code>
|
||||||
<br> <td >same as <code>rbegin(x)</code> </td>
|
<br>
|
||||||
|
<td>same as <code>rbegin(x)</code>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr >
|
<tr>
|
||||||
<a name="const_rend" ></a>
|
<a name="const_rend"></a>
|
||||||
<td ><code >const_rend(x)</code></td>
|
<td><code>const_rend(x)</code></td>
|
||||||
<td ><code >range_const_reverse_iterator<X>::type</code></td>
|
<td><code>range_const_reverse_iterator<X>::type</code></td>
|
||||||
<td ><code >range_const_reverse_iterator<X>::type( rend(x) )</code>
|
<td><code>range_const_reverse_iterator<X>::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><</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>></span>
|
||||||
|
<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>iterator</span><span class=special>></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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></span>
|
||||||
|
<span class=keyword>struct</span> <span class=identifier>range_iterator</span><span class=special><</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>></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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></span>
|
||||||
|
<span class=keyword>struct</span> <span class=identifier>range_const_iterator</span><span class=special><</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>></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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></span>
|
||||||
|
<span class=keyword>struct</span> <span class=identifier>range_size</span><span class=special><</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>></span>
|
||||||
|
<span class=special>{</span>
|
||||||
|
|
||||||
|
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>type</span><span class=special>;</span>
|
||||||
|
<span class=special>};</span>
|
||||||
|
|
||||||
|
<span class=special>}</span> <span class=comment>// namespace 'boost'</span>
|
||||||
|
|
||||||
|
<span class=keyword>namespace</span> <span class=identifier>Foo</span>
|
||||||
|
<span class=special>{</span>
|
||||||
|
<span class=comment>//
|
||||||
|
// The required functions. These should be defined in
|
||||||
|
// the same namespace as 'Pair', in this case
|
||||||
|
// in namespace 'Foo'.
|
||||||
|
//</span>
|
||||||
|
|
||||||
|
<span class=keyword>template</span><span class=special><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span><span class=identifier>T</span><span class=special>>&</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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span><span class=identifier>T</span><span class=special>>&</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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span><span class=identifier>T</span><span class=special>>&</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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span><span class=identifier>T</span><span class=special>>&</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><</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>></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><</span> <span class=identifier>Pair</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>>::</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><</span><span class=identifier>T</span><span class=special>>&</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><</span><span class=identifier>vector</span><span class=special>></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><</span><span class=keyword>int</span><span class=special>>::</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><</span><span class=keyword>int</span><span class=special>></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><</span><span class=identifier>iter</span><span class=special>></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><</span><span class=identifier>iter</span><span class=special>>&</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><</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special><</span><span class=identifier>iter</span><span class=special>></span> <span class=special>>::</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><</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special><</span><span class=identifier>iter</span><span class=special>></span> <span class=special>>::</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
141
doc/example.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -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>"a string"</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>;
|
</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><< </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><< </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><< </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><< </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><< </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><< </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>
|
||||||
|
@ -386,7 +386,7 @@ VAlign="top"><code>boost::range_const_reverse_iterator<X>::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<X>::type</code> if
|
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
||||||
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
||||||
otherwise.</TD>
|
otherwise.</TD>
|
||||||
@ -394,7 +394,7 @@ otherwise.</TD>
|
|||||||
<code>boost::range_reverse_iterator<X>::type(boost::end(a))</code>.</TD> </TR>
|
<code>boost::range_reverse_iterator<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<X>::type</code> if
|
<TD VAlign="top"><code>boost::range_reverse_iterator<X>::type</code> if
|
||||||
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<X>::type</code>
|
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator<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>
|
||||||
|
@ -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) \
|
||||||
|
@ -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
|
||||||
|
@ -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) \
|
||||||
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
@ -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 ) );
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
112
test/extension_mechanism.cpp
Executable 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user