forked from boostorg/range
Compare commits
93 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
6477d92683 | |||
ae8efa1436 | |||
846cbcea43 | |||
3f27b522c1 | |||
a29ddcbcca | |||
f7ffdde09f | |||
0909f0cc51 | |||
931bf86c87 | |||
920a874e3a | |||
a88312e955 | |||
6efc4ee478 | |||
c7047652d8 | |||
84a9126cc9 | |||
e6611aafb1 | |||
bd13c9082e | |||
af5431e553 | |||
5e470543ad | |||
3abdd3afd4 | |||
cfb03e4aee | |||
811d3da3eb | |||
4243a38acd | |||
7a5e8fba8e | |||
3b3cb0571c | |||
da43d13564 | |||
58eee2c6ef | |||
b1174d5433 | |||
3ce0264517 | |||
bf9925e2aa | |||
caac9c37c3 | |||
f3f71946a1 | |||
bf3ff8fd5d | |||
60450042a3 | |||
ea0e0c96e2 | |||
821c5c621b | |||
97b8964e51 | |||
af8171efdc | |||
a929adc492 | |||
77dff97861 | |||
e7f41d9aac | |||
7f5b192dfa | |||
4de4fbc46e | |||
df504d811a | |||
d2c2fec7a8 | |||
a6e1f784d0 | |||
63e1d006c9 | |||
789d2c3fe0 | |||
247ff6c8b8 | |||
e0e4055a9d | |||
230c7a245c | |||
a3d3c28ccc | |||
531339a51d | |||
68b1d06b39 | |||
8378643b44 | |||
7d81f9a845 | |||
ebca0b2a2a | |||
0dbf587323 | |||
e245cc6a7e | |||
6157440017 | |||
7b37911918 | |||
3e632e0a32 | |||
9657ab7b2b | |||
33bde55e1c | |||
be9bf983a8 | |||
87374d6dfe | |||
ab738f30ba | |||
12acb0fdf7 | |||
51c6547351 | |||
aa01efb722 | |||
4356af8d45 | |||
dc7d30bab6 | |||
b86b99190b | |||
65f5d654f7 | |||
00d991f460 | |||
f94261d0aa | |||
bea144c2a8 | |||
5a479378d6 | |||
e26056b475 | |||
deb05d7f62 | |||
d73fb64736 | |||
2f4e6004f3 | |||
ec8b51b82b | |||
716d34097b | |||
eb18ab0cc6 | |||
ebb9cf200c | |||
d2dca990db | |||
81b3665c8f | |||
129e5862d2 | |||
1494248e57 | |||
23625421f1 | |||
fd8f0bebd0 | |||
d78d5e3fd6 | |||
25ecc19ec1 | |||
3a452b498f |
542
doc/boost_range.html
Normal file
542
doc/boost_range.html
Normal file
@ -0,0 +1,542 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Boost.Range Range Implementation </title>
|
||||
<meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table >
|
||||
<tr >
|
||||
<td ><img src="../../../boost.png" width="100%" border="0"></td>
|
||||
<td ><h1 ><br>
|
||||
Boost.Range </h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Single Pass Range, Forward Range and Bidirectional Range Implementation</h2>
|
||||
|
||||
<ul >
|
||||
<li>
|
||||
<a href="#overview">Overview</a>
|
||||
<li >
|
||||
<a href="#Synopsis" >Synopsis</a>
|
||||
</li>
|
||||
<li >
|
||||
<a href="#Semantics" >Semantics</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#minimal_interface">Extending the library</a>
|
||||
</ul>
|
||||
<hr size="1" >
|
||||
|
||||
<a name="overview"></a>
|
||||
<h3>Overview</h3>
|
||||
<p>
|
||||
Four types of objects are currently supported by the library:
|
||||
<ul >
|
||||
<li >
|
||||
standard-like containers
|
||||
</li>
|
||||
<li >
|
||||
<code >std::pair<iterator,iterator></code>
|
||||
</li>
|
||||
<li >
|
||||
null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,
|
||||
<code >char*</code>, and <code >wchar_t*</code>)
|
||||
</li>
|
||||
<li >
|
||||
built-in arrays
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Even though the behavior of the primary templates are exactly such that standard
|
||||
containers will be supported by default, the requirements are much lower than
|
||||
the standard container requirements. For example, the utility class <a
|
||||
href="utility_class.html#iter_range"><code>iterator_range</code></a> implements
|
||||
the <a href="#minimal_interface">minimal interface</a> required to make the
|
||||
class a <a href="range.html#forward_range">Forward Range</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please also see <a href="range.html">Range concepts</a> for more details.
|
||||
</p>
|
||||
|
||||
<a name="Synopsis" ></a> <h3 >Synopsis</h3>
|
||||
|
||||
<p >
|
||||
|
||||
<pre>
|
||||
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||
<span class=special>{
|
||||
</span><span class=comment>//
|
||||
// Single Pass Range metafunctions
|
||||
//
|
||||
|
||||
</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><a href="#range_value"><span
|
||||
class=identifier>range_value</span></a><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><a href="#range_iterator"><span
|
||||
class=identifier>range_iterator</span></a><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><a href="#range_const_iterator"><span
|
||||
class=identifier>range_const_iterator</span></a><span class=special>;
|
||||
|
||||
</span><span class=comment>//
|
||||
// Forward Range metafunctions
|
||||
//
|
||||
|
||||
</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><a href="#range_difference"><span
|
||||
class=identifier>range_difference</span></a><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><a href="#range_size"><span
|
||||
class=identifier>range_size</span></a><span class=special>;
|
||||
|
||||
</span><span class=comment>//
|
||||
// Bidirectional Range metafunctions
|
||||
//
|
||||
|
||||
</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><a
|
||||
href="#range_reverse_iterator"><span
|
||||
class=identifier>range_reverse_iterator</span></a><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><a
|
||||
href="#range_const_reverse_iterator"><span
|
||||
class=identifier>range_const_reverse_iterator</span></a><span class=special>;
|
||||
|
||||
</span><span class=comment>//
|
||||
// Special metafunctions
|
||||
//
|
||||
|
||||
</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><a href="#range_result_iterator"><span
|
||||
class=identifier>range_result_iterator</span></a><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><a
|
||||
href="#range_reverse_result_iterator"><span
|
||||
class=identifier>range_reverse_result_iterator</span></a><span class=special>;
|
||||
|
||||
</span><span class=comment>//
|
||||
// Single Pass Range functions
|
||||
//
|
||||
|
||||
</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></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>bool
|
||||
</span><a href="#empty"><span class=identifier>empty</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||
|
||||
</span><span class=comment>//
|
||||
// Forward Range functions
|
||||
//
|
||||
|
||||
</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></span><span class=keyword>typename </span><span class=identifier>range_size</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#size"><span class=identifier>size</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||
|
||||
</span><span class=comment>//
|
||||
// Bidirectional Range functions
|
||||
//
|
||||
|
||||
</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></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>c </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></span><span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type
|
||||
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=keyword>const </span><span
|
||||
class=identifier>T</span><span class=special>& </span><span class=identifier>c </span><span class=special>);
|
||||
</span>
|
||||
<span class=comment>//
|
||||
// Special const Range functions
|
||||
//
|
||||
</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>typename </span><span class=identifier>range_const_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span>
|
||||
<a href="#const_begin"><span class=identifier>const_begin</span></a><span class=special>(</span><span class=keyword> const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </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>typename </span><span class=identifier>range_const_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span>
|
||||
<a href="#const_end"><span class=identifier>const_end</span></a><span class=special>(</span><span class=keyword> const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </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>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span>
|
||||
<a href="#const_rbegin"><span class=identifier>const_rbegin</span></a><span class=special>(</span><span class=keyword> const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </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>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span>
|
||||
<a href="#const_rend"><span class=identifier>const_rend</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </span><span class=special>);</span>
|
||||
|
||||
<span class=special>} </span><span class=comment>// namespace 'boost'
|
||||
</span>
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<a name="Semantics" ></a> <h3 >Semantics</h3>
|
||||
|
||||
<h4>notation</h4>
|
||||
<p>
|
||||
<table cellpadding="5" border="1">
|
||||
<tr>
|
||||
<th>Type
|
||||
<th>Object
|
||||
<th>Describes
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>X</code>
|
||||
<td><code>x</code>
|
||||
<td>any type
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>T</code> </td>
|
||||
<td><code>t</code>
|
||||
<td>denotes behavior of the primary templates</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>P</code>
|
||||
<td><code>p</code>
|
||||
<td>denotes <code>std::pair<iterator,iterator></code>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>A[sz]</code>
|
||||
<td><code>a</code>
|
||||
<td>denotes an array of type <code>A</code> of size <code>sz</code>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><code>Char*</code>
|
||||
<td><code>s</code>
|
||||
<td>denotes either <code>char*</code> or <code>wchar_t*</code>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please notice in tables below that when four lines appear in a cell, the first
|
||||
line will describe the primary template, the second line pairs of iterators, the
|
||||
third line arrays and the last line null-terminated strings.
|
||||
</p>
|
||||
<h4>Metafunctions</h4>
|
||||
<p>
|
||||
<table border="1" cellpadding="5" >
|
||||
<tr >
|
||||
<th >Expression</th>
|
||||
<th >Return type</th>
|
||||
<th >Complexity</th>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_value" ></a>
|
||||
<td ><code >range_value<X>::type</code></td>
|
||||
<td ><code >T::value_type</code><br>
|
||||
<code >boost::iterator_value<P::first_type>::type</code><br>
|
||||
<code >A</code><br>
|
||||
<code>Char</code>
|
||||
<td >compile time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_iterator" ></a>
|
||||
<td ><code >range_iterator<X>::type</code></td>
|
||||
<td ><code >T::iterator</code><br>
|
||||
<code >P::first_type</code><br>
|
||||
<code >A*</code><br>
|
||||
<code>Char*</code>
|
||||
<td >compile time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_const_iterator" ></a>
|
||||
<td ><code >range_const_iterator<X>::type</code></td>
|
||||
<td ><code >T::const_iterator</code><br>
|
||||
<code >P::first_type</code><br>
|
||||
<code >const A*</code><br>
|
||||
<code>const Char*</code>
|
||||
<td >compile time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_difference" ></a>
|
||||
<td ><code >range_difference<X>::type</code></td>
|
||||
<td ><code >T::difference_type</code><br>
|
||||
<code
|
||||
>boost_iterator_difference<P::first_type>::type</code><br>
|
||||
<code >std::ptrdiff_t</code><br>
|
||||
<code >std::ptrdiff_t</code><br>
|
||||
<td >compile time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_size" ></a>
|
||||
<td ><code >range_size<X>::type</code></td>
|
||||
<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>
|
||||
<td >compile time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="range_result_iterator" ></a>
|
||||
<td ><code >range_result_iterator<X>::type</code></td>
|
||||
<td ><code >range_const_iterator<X>::type</code> if <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>
|
||||
<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>
|
||||
|
||||
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
The special metafunctions <code>range_result_iterator</code> and <code>range_reverse_result_iterator</code>
|
||||
are not part of any Range concept, but they are very useful when implementing
|
||||
certain Range classes like <a
|
||||
href="utility_class.html#sub_range"><code>sub_range</code></a> because of their
|
||||
ability to select iterators based on constness.
|
||||
</p>
|
||||
|
||||
<h4>Functions</h4>
|
||||
<p>
|
||||
<table border="1" cellpadding="5" >
|
||||
<tr >
|
||||
<th >Expression</th>
|
||||
<th >Return type</th>
|
||||
<th >Returns</th>
|
||||
<th >Complexity</th>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="begin" ></a>
|
||||
<td ><code >begin(x)</code></td>
|
||||
<td ><code >range_result_iterator<X>::type</code></td>
|
||||
<td ><code >t.begin()</code><br>
|
||||
<code >p.first</code><br>
|
||||
<code >a</code><br>
|
||||
<code>s</code>
|
||||
<td >constant time</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="end" ></a>
|
||||
<td ><code >end(x)</code></td>
|
||||
<td ><code >range_result_iterator<X>::type</code></td>
|
||||
<td ><code >t.end()</code><br>
|
||||
<code >p.second</code><br>
|
||||
<code >a + sz</code> <br>
|
||||
<code >s + std::char_traits<X>::length( s )</code> if <code >X</code> is <code >Char*</code>
|
||||
<br>
|
||||
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br>
|
||||
|
||||
|
||||
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
||||
constant time otherwise</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="empty" ></a>
|
||||
<td ><code >empty(x)</code></td>
|
||||
<td ><code >bool</code></td>
|
||||
<td ><code >begin(x) == end( x )</code><br>
|
||||
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
||||
constant time otherwise<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="size" ></a>
|
||||
<td ><code >size(x)</code></td>
|
||||
<td ><code >range_size<X>::type</code></td>
|
||||
<td ><code >t.size()</code><br>
|
||||
<code>std::distance(p.first,p.second)</code><br>
|
||||
<code >sz</code><br>
|
||||
<code>end(s) - s</code>
|
||||
|
||||
<td >linear if <code >X</code> is <code >Char*</code> <br>
|
||||
or if <code >std::distance()</code> is linear <br>
|
||||
constant time otherwise</td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="rbegin" ></a>
|
||||
<td ><code >rbegin(x)</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 >same as <code>end(x)</code> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="rend" ></a>
|
||||
<td ><code >rend(x)</code></td>
|
||||
<td ><code >range_reverse_result_iterator<X>::type</code></td>
|
||||
<td ><code >range_reverse_result_iterator<X>::type( begin(x) )</code>
|
||||
<td >same as <code>begin(x)</code></td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="const_begin" ></a>
|
||||
<td ><code >const_begin(x)</code></td>
|
||||
<td ><code >range_const_iterator<X>::type</code></td>
|
||||
<td ><code >range_const_iterator<X>::type( begin(x) )</code>
|
||||
<br> <td >same as <code>begin(x)</code> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="const_end" ></a>
|
||||
<td ><code >const_end(x)</code></td>
|
||||
<td ><code >range_const_iterator<X>::type</code></td>
|
||||
<td ><code >range_const_iterator<X>::type( end(x) )</code>
|
||||
<td >same as <code>end(x)</code></td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="const_rbegin" ></a>
|
||||
<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( rbegin(x) )</code>
|
||||
<br> <td >same as <code>rbegin(x)</code> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<a name="const_rend" ></a>
|
||||
<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( rend(x) )</code>
|
||||
<td >same as <code>rend(x)</code></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The special <code>const</code> functions are not part of any Range concept,
|
||||
but are very useful when you want to document clearly that your code is
|
||||
read-only.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name=minimal_interface></a> <h3>Extending the library</h3>
|
||||
<p>
|
||||
The primary templates in this library are implemented such that standard
|
||||
containers will work automatically and so will <code>boost::<a
|
||||
href=../../array/index.html>array</a></code>. Below is given an overview of
|
||||
which member functions and member types a class must specify to
|
||||
be useable as a certain Range concept.
|
||||
</p>
|
||||
<p>
|
||||
<table cellpadding="5" border="1">
|
||||
<tr>
|
||||
<th>Member function</th>
|
||||
<th>Related concept</th>
|
||||
<tr>
|
||||
<td><code>begin()</code></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>end()</code> </td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size()</code></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
Notice that <code>rbegin()</code> and <code>rend()</code> member functions
|
||||
are not needed even though the container can support bidirectional iteration.
|
||||
</p>
|
||||
<p>
|
||||
The required member types are:
|
||||
</p>
|
||||
<p>
|
||||
<table cellpadding="5" border="1">
|
||||
<tr>
|
||||
<th>Member type</th>
|
||||
<th>Related concept</th>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><code>value_type</code></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>iterator</code></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>const_iterator</code></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>difference_type</code></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_type</code></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</p>
|
||||
<p>
|
||||
Again one should notice that member types <code>reverse_iterator</code> and
|
||||
<code>const_reverse_iterator</code> are not needed.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
64
doc/examples.html
Executable file
64
doc/examples.html
Executable file
@ -0,0 +1,64 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Examples </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range </h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 >Examples</h2><a name="Examples" ></a>
|
||||
<p >
|
||||
Some examples are given in the accompanying test files:
|
||||
</p>
|
||||
<ul >
|
||||
<li >
|
||||
<a href="../test/string.cpp" target="_self" ><code >string.cpp</code></a>
|
||||
</li>
|
||||
shows how to implement a container version of <code >std::find()</code> that
|
||||
works with <code >char[],wchar_t[],char*,wchar_t*.</code>
|
||||
<li >
|
||||
<a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a>
|
||||
|
||||
</li>
|
||||
shows the replace example from the introduction.
|
||||
|
||||
<li> <a href="../test/iterator_range.cpp">iterator_range.cpp</a>
|
||||
<li> <a href="../test/sub_range.cpp">sub_range.cpp</a>
|
||||
<li> <a href="../test/iterator_pair.cpp">iterator_pair.cpp</a>
|
||||
<li> <a href="../test/reversible_range.cpp">reversible_range.cpp</a>
|
||||
<li> <a href="../test/std_container.cpp">std_container.cpp</a>
|
||||
<li> <a href="../test/array.cpp">array.cpp</a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
138
doc/faq.html
Executable file
138
doc/faq.html
Executable file
@ -0,0 +1,138 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range FAQ </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<h2 >FAQ</h2> <a name="FAQ" ></a>
|
||||
<ol >
|
||||
<li >
|
||||
<i>Why is there no difference between <code >range_iterator<C>::type</code>
|
||||
and <code >range_const_iterator<C>::type</code> for <code>std::pair<iterator, iterator></code></i>.
|
||||
</li>
|
||||
<p >
|
||||
In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>.
|
||||
When it is possible to come up with one, the client might choose to construct a <code >std::pair<const_iterator,const_iterator></code>
|
||||
object.
|
||||
</p>
|
||||
<p>
|
||||
Note that an <a href="utility_class.html#iter_range">iterator_range</a>
|
||||
is somewhat more convenient than a <code>pair</code> and that a <a
|
||||
href="utility_class.html#sub_range"><code>sub_range</code></a> do
|
||||
propagate const-ness. </p>
|
||||
|
||||
<li >
|
||||
<i>Why is there not supplied more types or more functions?</i>
|
||||
<p >
|
||||
The library has been kept small because its current interface will
|
||||
serve most
|
||||
purposes. If and when a genuine need arises for more functionality, it can be
|
||||
implemented.
|
||||
</p>
|
||||
</li>
|
||||
<li >
|
||||
<i>How should I implement generic algorithms for ranges?</i>
|
||||
<p >
|
||||
One should always start with a generic algorithm that takes two iterators (or
|
||||
more) as input. Then use Boost.Range to build handier versions on top of the
|
||||
iterator based algorithm. Please notice that once the range version of the
|
||||
algorithm is done, it makes sense <i>not</i> to expose the iterator version in
|
||||
the public interface.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<i>Why is there no Incrementable Range concept?</i>
|
||||
<p>
|
||||
Even though we speak of incrementable iterators, it would not make
|
||||
much sense for ranges; for example, we cannot determine the size and
|
||||
emptiness of a range since we cannot even compare
|
||||
its iterators.
|
||||
</p>
|
||||
<p>
|
||||
Note also that incrementable iterators are derived from output
|
||||
iterators and so there exist no output range.
|
||||
</p>
|
||||
</li>
|
||||
<!--
|
||||
<li>
|
||||
<i>Should I use qualified syntax, for example
|
||||
<blockquote><pre>
|
||||
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>); </span>
|
||||
</pre></blockquote>
|
||||
instead of
|
||||
<blockquote>
|
||||
<pre><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>;</span>
|
||||
<span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>)</span></pre></blockquote>
|
||||
when calling functions in this library? If so, can I still rely on argument
|
||||
dependent lookup (ADL) to kick in?</i>
|
||||
<p>
|
||||
The answer to the first question is that "it's up to you". The
|
||||
answer to the second question is Yes. Normally qualified syntax
|
||||
disables ADL, but the functions are implemented in a special
|
||||
manner that preserves ADL properties. The trick was explained by
|
||||
Daniel Frey on comp.lang.std.c++ in the thread "Whence Swap" and
|
||||
it is best explained by some code: <blockquote>
|
||||
<pre>
|
||||
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||
<span class=special>{
|
||||
</span><span class=keyword>namespace </span><span class=identifier>range_detail
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||
</span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>:</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </span><span class=special>)
|
||||
</span><span class=special>{ </span><span class=comment>/* normal implementation */ </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>typename </span><span class=identifier>range_iterator</span><span class=special><</span><span class=identifier>T</span><span class=special>>::</span><span class=identifier>type </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>r </span><span class=special>)
|
||||
</span><span class=special>{
|
||||
</span><span class=comment>//
|
||||
// Create ADL hook
|
||||
//
|
||||
</span><span class=keyword>using </span><span class=identifier>range_detail</span><span class=special>::</span><span class=identifier>begin</span><span class=special>;
|
||||
</span><span class=keyword>return </span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>r </span><span class=special>);
|
||||
</span><span class=special>}</span>
|
||||
<span class=special>} </span>
|
||||
</pre>
|
||||
</blockquote>
|
||||
Cool indeed!
|
||||
</p>
|
||||
-->
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
171
doc/headers.html
Executable file
171
doc/headers.html
Executable file
@ -0,0 +1,171 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Headers </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<h2 >Library headers</h2><a name="Library headers" ></a>
|
||||
<table cellpadding="5" border="1" >
|
||||
<tr >
|
||||
<th >Header</th>
|
||||
<th >Includes</th>
|
||||
<th>Related concept </th>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range.hpp></code></td>
|
||||
<td >everything</td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/metafunctions.hpp></code></td>
|
||||
<td >every metafunction</td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/functions.hpp></code></td>
|
||||
<td >every function</td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/value_type.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_value" >range_value</a></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_iterator"
|
||||
>range_iterator</a></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/const_iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_const_iterator"
|
||||
>range_const_iterator</a></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/difference_type.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_difference"
|
||||
>range_difference</a></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/size_type.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_size" >range_size</a></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/result_iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_result_iterator"
|
||||
>range_result_iterator</a></td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/reverse_iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_reverse_iterator" >range_reverse_iterator</a></td>
|
||||
<td><a href="range.html#bidirectional_range">Bidirectional Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/const_reverse_iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_const_reverse_iterator" >range_const_reverse_iterator</a></td>
|
||||
<td><a href="range.html#bidirectional_range">Bidirectional Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/reverse_result_iterator.hpp></code></td>
|
||||
<td ><a href="boost_range.html#range_reverse_result_iterator">range_reverse_result_iterator</a></td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/begin.hpp></code></td>
|
||||
<td >
|
||||
<a href="boost_range.html#begin" >begin</a> and
|
||||
<a href="boost_range.html#const_begin" >const_begin</a>
|
||||
</td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/end.hpp></code></td>
|
||||
<td >
|
||||
<a href="boost_range.html#end" >end</a> and
|
||||
<a href="boost_range.html#const_end" >const_end</a>
|
||||
</td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/empty.hpp></code></td>
|
||||
<td ><a href="boost_range.html#empty" >empty</a></td>
|
||||
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/size.hpp></code></td>
|
||||
<td ><a href="boost_range.html#size" >size</a></td>
|
||||
<td><a href="range.html#forward_range">Forward Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/rbegin.hpp></code></td>
|
||||
<td >
|
||||
<a href="boost_range.html#rbegin" >rbegin</a> and
|
||||
<a href="boost_range.html#const_rbegin" >const_rbegin</a>
|
||||
</td>
|
||||
<td><a href="range.html#bidirectional_range">Bidirectional Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/rend.hpp></code></td>
|
||||
<td >
|
||||
<a href="boost_range.html#rend" >rend</a> and
|
||||
<a href="boost_range.html#const_rend" >const_rend</a>
|
||||
</td>
|
||||
<td><a href="range.html#bidirectional_range">Bidirectional Range</a> </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/iterator_range.hpp></code></td>
|
||||
<td ><a href="utility_class.html#iter_range"
|
||||
>iterator_range</a></td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
<tr >
|
||||
<td ><code ><boost/range/sub_range.hpp></code></td>
|
||||
<td ><a href="utility_class.html#sub_range" >sub_range</a></td>
|
||||
<td>- </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<br
|
||||
</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
78
doc/history_ack.html
Executable file
78
doc/history_ack.html
Executable file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range History and Acknowledgement </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td><img src="../../../boost.png" border="0" ></td>
|
||||
<td><h1 align="center">Boost.Range </h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 >History and Acknowledgement</h2><a name="History" ></a>
|
||||
<p >
|
||||
The library have been under way for a long time. Dietmar K<>hl originally
|
||||
intended to submit an <code >array_traits</code> class template which
|
||||
had most of the functionality present now, but only for arrays and standard
|
||||
containers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Meanwhile work on algorithms for containers in various contexts showed the
|
||||
need for handling pairs of iterators, and string libraries needed special
|
||||
treatment of character arrays. In the end it made sense to formalize the
|
||||
minimal requirements of these similar concepts. And the results are the
|
||||
Range concepts found in this library. </p>
|
||||
|
||||
<p>
|
||||
The term Range was adopted because of paragraph <code>24.1/7</code> from the
|
||||
C++ standard: <blockquote>
|
||||
Most of the library's algorithmic templates that operate on data
|
||||
structures have interfaces that use ranges. A <i>range</i> is a pair of
|
||||
iterators that designate the beginning and end of the computation. A
|
||||
range [i, i) is an empty range; in general, a range [i, j) refers to
|
||||
the elements in the data structure starting with the one pointed to
|
||||
by i and up to but not including the one pointed to by j. Range [i,
|
||||
j) is valid if and only if j is reachable from i. The result of the
|
||||
application of functions in the library to invalid ranges is
|
||||
undefined.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Special thanks goes to
|
||||
<ul>
|
||||
<li> Pavol Droba for help with documentation and implementation
|
||||
<li> Pavel Vozenilek for help with porting the library
|
||||
<li> Jonathan Turkanis and John Torjo for help with documentation
|
||||
<li> Hartmut Kaiser for being review manager
|
||||
</ul>
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
164
doc/intro.html
Executable file
164
doc/intro.html
Executable file
@ -0,0 +1,164 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Introduction </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>
|
||||
Generic algorithms have so far been specified in terms of two or more
|
||||
iterators. Two iterators would together form a range of values that the
|
||||
algorithm could work on. This leads to a very general interface, but also
|
||||
to a somewhat clumsy use of the algorithms with redundant specification
|
||||
of container names. Therefore we would like to raise the abstraction level
|
||||
for algorithms so they specify their interface in terms of <a
|
||||
href=range.html>Ranges</a> as much as possible.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The most common form of ranges we are used to work with is standard library
|
||||
containers. However, one
|
||||
often finds it desirable to extend that code to work with other types that
|
||||
offer
|
||||
enough functionality to satisfy the needs of the generic code
|
||||
<i>if a suitable layer of indirection is applied </i>. For
|
||||
example, raw arrays are often suitable for use with generic code that
|
||||
works with containers, provided a suitable adapter is used. Likewise, null
|
||||
terminated strings can be treated as containers of characters, if suitably
|
||||
adapted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This library therefore provides the means to adapt standard-like
|
||||
containers,
|
||||
null terminated strings, <code>std::pairs</code> of iterators, and raw
|
||||
arrays (and more), such that the same generic code can work with them all.
|
||||
The basic idea is to add another layer of indirection using <a
|
||||
href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and
|
||||
free-standing functions so syntactic and/or semantic differences can be removed.
|
||||
</p>
|
||||
|
||||
<p >
|
||||
The main advantages are
|
||||
<ul >
|
||||
<li >
|
||||
simpler implementation and specification of generic range algorithms
|
||||
</li>
|
||||
<li >
|
||||
more flexible, compact and maintainable client code
|
||||
</li>
|
||||
<li >
|
||||
correct handling of null-terminated strings
|
||||
</li>
|
||||
<li >
|
||||
safe use of built-in arrays (for legacy code; why else would you use
|
||||
built-in arrays?) </li>
|
||||
|
||||
</ul>
|
||||
</p>
|
||||
<p >
|
||||
Below are given a small example (the complete example can be found <a href="../test/algorithm_example.cpp" target="_self" >here</a>
|
||||
):
|
||||
<blockquote>
|
||||
<pre >
|
||||
<span class=comment>
|
||||
//
|
||||
// example: extracting bounds in a generic algorithm
|
||||
//
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_iterator</span><span class=special>< </span><span class=identifier>ForwardReadableRange </span><span class=special>>::</span><span class=identifier>type
|
||||
</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>ForwardReadableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value </span><span class=special>)
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
|
||||
</span><span class=special>}
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_const_iterator</span><span class=special>< </span><span
|
||||
class=identifier>ForwardReadableRange </span><span class=special>>::</span><span class=identifier>type
|
||||
</span><span class=identifier>find</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardReadableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value </span><span class=special>)
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
|
||||
</span><span class=special>}
|
||||
|
||||
</span><span class=comment>//
|
||||
// replace first value and return its index
|
||||
//
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>>
|
||||
</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>ForwardReadableWriteableRange </span><span class=special>>::</span><span class=identifier>type
|
||||
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>& </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>& </span><span class=identifier>replacement </span><span class=special>)
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_iterator</span><span class=special>< </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>>::</span><span class=identifier>type </span><span class=identifier>found </span><span class=special>= </span><span class=identifier>find</span><span class=special>( </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>value </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>if</span><span class=special>( </span><span class=identifier>found </span><span class=special>!= </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>) </span><span class=special>)
|
||||
</span><span class=special>*</span><span class=identifier>found </span><span class=special>= </span><span class=identifier>replacement</span><span class=special>;
|
||||
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>distance</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>found </span><span class=special>);
|
||||
</span><span class=special>}
|
||||
|
||||
</span><span class=comment>//
|
||||
// usage
|
||||
//
|
||||
</span><span class=keyword>const </span><span class=keyword>int </span><span class=identifier>N </span><span class=special>= </span><span class=number>5</span><span class=special>;
|
||||
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>> </span><span class=identifier>my_vector</span><span class=special>;
|
||||
</span><span class=keyword>int </span><span class=identifier>values</span><span class=special>[] </span><span class=special>= </span><span class=special>{ </span><span class=number>1</span><span class=special>,</span><span class=number>2</span><span class=special>,</span><span class=number>3</span><span class=special>,</span><span class=number>4</span><span class=special>,</span><span class=number>5</span><span class=special>,</span><span class=number>6</span><span class=special>,</span><span class=number>7</span><span class=special>,</span><span class=number>8</span><span class=special>,</span><span class=number>9 </span><span class=special>};
|
||||
</span>
|
||||
<span class=identifier>my_vector</span><span class=special>.</span><span
|
||||
class=identifier>assign</span><span class=special>( </span><span class=identifier>values</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>values </span><span class=special>) </span><span class=special>);</span>
|
||||
</span><span class=keyword>typedef </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><span class=keyword>int</span><span class=special>>::</span><span class=identifier>iterator </span><span class=identifier>iterator</span><span class=special>;
|
||||
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>> </span><span class=identifier>my_view</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>),
|
||||
</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>) </span><span class=special>+ </span><span class=identifier>N </span><span class=special>);
|
||||
</span><span class=keyword>char </span><span class=identifier>str_val</span><span class=special>[] </span><span class=special>= </span><span class=string>"a string"</span><span class=special>;
|
||||
</span><span class=keyword>char</span><span class=special>* </span><span class=identifier>str </span><span class=special>= </span><span class=identifier>str_val</span><span class=special>;
|
||||
|
||||
</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=special><< </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=literal>'a'</span><span class=special>, </span><span class=literal>'b' </span><span class=special>);
|
||||
</span>
|
||||
<span class=comment>// prints '3', '5' and '0' </span>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
By using the free-standing functions and <a
|
||||
href="../../mpl/doc/index.html#metafunctions">metafunctions</a>, the code automatically
|
||||
works for all the types supported by this library; now and in the future.
|
||||
Notice that we have to
|
||||
provide two version of <code >find()</code> since we cannot forward a non-const
|
||||
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
|
||||
Forwarding Problem</a> ).
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
93
doc/portability.html
Executable file
93
doc/portability.html
Executable file
@ -0,0 +1,93 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Portability </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Portability</h2><a name="Portability" ></a>
|
||||
|
||||
<p>
|
||||
A huge effort has been made to port the library to as many compilers as possible.
|
||||
<!-- The results of the test-suites can be found <a
|
||||
href="http://boost.sourceforge.net/regression-logs/developer/range.html">here</a
|
||||
>.--> </p>
|
||||
|
||||
<p>
|
||||
Full support for built-in arrays require that the compiler supports class
|
||||
template partial specialization. For non-conforming compilers there might be a
|
||||
chance that it works anyway thanks to workarounds in the type traits library.
|
||||
</p>
|
||||
<p >
|
||||
Notice also that some compilers cannot do function template ordering properly.
|
||||
In that case one must rely of <a
|
||||
href="boost_range.html#range_result_iterator"><code >range_result_iterator</code></a>
|
||||
and a single function definition instead of overloaded versions for const and
|
||||
non-const arguments.
|
||||
|
||||
So if one cares about old compilers, one should not pass rvalues to the
|
||||
functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For maximum portability you should follow these guidelines:
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
do not use built-in arrays,
|
||||
<li>
|
||||
do not pass rvalues to <a
|
||||
href="boost_range.html#begin"><code>begin()</code></a>, <a
|
||||
href="boost_range.html#end"><code>end()</code></a> and <a href="utility_class.html#iter_range">
|
||||
<code>iterator_range</code></a> Range constructors and assignment operators,
|
||||
<li>
|
||||
use <a href="boost_range.html#const_begin"><code>const_begin()</code></a>
|
||||
and <a href="boost_range.html#const_begin"><code>const_end()</code></a>
|
||||
whenever your code by intention is read-only; this will also solve
|
||||
most rvalue problems,
|
||||
<li>
|
||||
do not rely on ADL:
|
||||
<ul>
|
||||
<li>
|
||||
if you overload functions, include that header <i>before</i> the headers in this
|
||||
library,
|
||||
<li>
|
||||
put all overloads in namespace <code>boost</code>.
|
||||
</ul>
|
||||
|
||||
</ol>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
470
doc/range.html
Executable file
470
doc/range.html
Executable file
@ -0,0 +1,470 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) Jeremy Siek 2000
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. Silicon Graphics makes no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<Title>Range Concepts</Title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</HEAD>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range </h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Range concepts </h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#overview">Overview</a>
|
||||
<li>
|
||||
<a href="#single_pass_range">Single Pass Range</a>
|
||||
<li>
|
||||
<a href="#forward_range">Forward Range</a>
|
||||
<li>
|
||||
<a href="#bidirectional_range">Bidirectional Range</a>
|
||||
<li>
|
||||
<a href="#random_access_range">Random Access Range</a>
|
||||
</ul>
|
||||
|
||||
<a name="overview"></a>
|
||||
<hr>
|
||||
<h3>Overview</h3>
|
||||
|
||||
<p>
|
||||
A Range is a <i>concept</i> similar to the STL <a
|
||||
href="http://www.sgi.com/Technology/STL/Container.html">Container</a> concept. A
|
||||
Range provides iterators for accessing a closed-open range
|
||||
<code>[first,one_past_last)</code> of elements and provides
|
||||
information about the number of elements in the Range. However, a Range has
|
||||
fewer requirements than a Container.
|
||||
</p>
|
||||
<p>
|
||||
The motivation for the Range concept is
|
||||
that there are many useful Container-like types that do not meet the full
|
||||
requirements of Container, and many algorithms that can be written with this
|
||||
reduced set of requirements. In particular, a Range does not necessarily
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
own the elements that can be accessed through it,
|
||||
<li>
|
||||
have copy semantics,
|
||||
<!--
|
||||
<li>
|
||||
require that the associated reference type is a real C++ reference.
|
||||
-->
|
||||
</ul>
|
||||
|
||||
|
||||
Because of the second requirement, a Range object must be passed by
|
||||
(const or non-const) reference in generic code.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
The operations that can be performed on a Range is dependent on the
|
||||
<a href="../../iterator/doc/new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal">traversal
|
||||
category</a> of the underlying iterator type. Therefore
|
||||
the range concepts are named to reflect which traversal category its
|
||||
iterators support. See also <a href="style.html">terminology and style guidelines.</a>
|
||||
for more information about naming of ranges.</p>
|
||||
|
||||
<p> The concepts described below specifies associated types as
|
||||
<a href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and all
|
||||
functions as free-standing functions to allow for a layer of indirection. </p>
|
||||
|
||||
<hr>
|
||||
<a name="single_pass_range">
|
||||
<H2>Single Pass Range</H2>
|
||||
|
||||
<h3>Notation</h3>
|
||||
<Table>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>X</code></TD>
|
||||
<TD VAlign="top">A type that is a model of Single Pass Range.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>a</code></TD>
|
||||
<TD VAlign="top">Object of type <code>X</code>.</TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
A range X where <code>range_iterator<X>::type</code> is a model of <a
|
||||
href="../../iterator/doc/new-iter-concepts.html#single-pass-iterators-lib-single-pass-iterators">
|
||||
Single Pass Iterator</a>
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<table border="1" cellpadding="5">
|
||||
<TR>
|
||||
<TD VAlign="top">Value type</TD>
|
||||
<TD VAlign="top"><code>range_value<X>::type</code></TD>
|
||||
<TD VAlign="top">The type of the object stored in a Range.
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Iterator type</TD>
|
||||
<TD VAlign="top"><code>range_iterator<X>::type</code></TD>
|
||||
<TD VAlign="top">The type of iterator used to iterate through a Range's elements.
|
||||
The iterator's value type is expected to be the Range's value type. A
|
||||
conversion from the iterator type to the const iterator type must exist.
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Const iterator type</TD>
|
||||
<TD VAlign="top"><code>range_const_iterator<X>::type</code></TD>
|
||||
<TD VAlign="top">A type of iterator that may be used to examine, but not to
|
||||
modify, a Range's elements.</TD>
|
||||
</TR>
|
||||
<!--
|
||||
<TR>
|
||||
<TD VAlign="top">Reference type</TD>
|
||||
<TD VAlign="top"><code>reference_of<X>::type</code></TD>
|
||||
<TD VAlign="top">A type that behaves like a reference to the Range's value type. <a href="#1">[1]</a></TD>
|
||||
</TR>
|
||||
-->
|
||||
</table>
|
||||
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
The following expressions must be valid.
|
||||
<p>
|
||||
|
||||
<Table border="1" cellpadding="5">
|
||||
<TR>
|
||||
<TH>Name</TH>
|
||||
<TH>Expression</TH>
|
||||
<TH>Return type</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Beginning of range</TD>
|
||||
<TD VAlign="top"><code>begin(a)</code></TD>
|
||||
<TD VAlign="top"><code>range_iterator<X>::type</code> if
|
||||
<code>a</code> is mutable, <code>range_const_iterator<X>::type</code>
|
||||
otherwise</TD> </TR>
|
||||
<TR>
|
||||
<TD VAlign="top">End of range</TD>
|
||||
<TD VAlign="top"><code>end(a)</code></TD>
|
||||
<TD VAlign="top"><code>range_iterator<X>::type</code> if
|
||||
<code>a</code> is mutable, <code>range_const_iterator<X>::type</code>
|
||||
otherwise</TD>
|
||||
</TR>
|
||||
<tr>
|
||||
<TD VAlign="top">Is range empty?</TD>
|
||||
<TD VAlign="top"><code>empty(a)</code></TD>
|
||||
<TD VAlign="top">Convertible to <code>bool</code></TD>
|
||||
</TR>
|
||||
</table>
|
||||
<h3>Expression semantics</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Expression</TH>
|
||||
<TH>Semantics</TH>
|
||||
<TH>Postcondition</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>begin(a)</code></TD>
|
||||
<TD VAlign="top">Returns an iterator pointing to the first element in the Range.</TD>
|
||||
<TD VAlign="top"><code>begin(a)</code> is either dereferenceable or past-the-end.
|
||||
It is past-the-end if and only if <code>size(a) == 0</code>.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>end(a)</code></TD>
|
||||
<TD VAlign="top">Returns an iterator pointing one past the last element in the
|
||||
Range.</TD>
|
||||
<TD VAlign="top"><code>end(a)</code> is past-the-end.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>empty(a)</code></TD>
|
||||
<TD VAlign="top">Equivalent to <code>begin(a) == end(a)</code>. (But possibly
|
||||
faster.)</TD>
|
||||
<TD VAlign="top"> - </TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
<h3>Complexity guarantees</h3>
|
||||
|
||||
All three functions are at most amortized linear time. For most practical
|
||||
purposes, one can expect <code>begin(a)</code>, <code>end(a)</code> and <code>empty(a)</code>
|
||||
to be amortized constant time.
|
||||
|
||||
<h3>Invariants</h3>
|
||||
<Table border>
|
||||
<TR>
|
||||
<TD VAlign="top">Valid range</TD>
|
||||
<TD VAlign="top">For any Range <code>a</code>, <code>[begin(a),end(a))</code> is
|
||||
a valid range, that is, <code>end(a)</code> is reachable from <code>begin(a)</code>
|
||||
in a finite number of increments.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Completeness</TD>
|
||||
<TD VAlign="top">An algorithm that iterates through the range <code>[begin(a),end(a))</code>
|
||||
will pass through every element of <code>a</code>.</TD>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<h3>See also</h3>
|
||||
<p>
|
||||
<A href="http://www.sgi.com/Technology/STL/Container.html">Container</A>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name=forward_range><h2>Forward Range</h2>
|
||||
|
||||
<h3>Notation</h3>
|
||||
<Table>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>X</code></TD>
|
||||
<TD VAlign="top">A type that is a model of Forward Range.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>a</code></TD>
|
||||
<TD VAlign="top">Object of type <code>X</code>.</TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
<h3>Description</h3>
|
||||
<p>
|
||||
A range <code>X</code> where <code>range_iterator<X>::type</code> is a model
|
||||
of <a
|
||||
href="../../iterator/doc/new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators">Forward Traversal Iterator</a>
|
||||
</p>
|
||||
|
||||
<h3>Refinement of</h3> <a href="#single_pass_range">Single Pass
|
||||
Range</a>
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<table cellpadding="5" border="1">
|
||||
<TR>
|
||||
<TD VAlign="top">Distance type</TD>
|
||||
<TD VAlign="top"><code>range_difference<X>::type</code></TD>
|
||||
<TD VAlign="top">A signed integral type used to represent the distance between
|
||||
two of the Range's iterators. This type must be the same as the iterator's
|
||||
distance type.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Size type</TD>
|
||||
<TD VAlign="top"><code>range_size<X>::type</code></TD>
|
||||
<TD VAlign="top">An unsigned integral type that can represent any nonnegative
|
||||
value of the Range's distance type.</TD>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<table border="1" cellpadding="5">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Expression</th>
|
||||
<th>Return type</th>
|
||||
</tr>
|
||||
<TR>
|
||||
<TD VAlign="top">Size of range</TD>
|
||||
<TD VAlign="top"><code>size(a)</code></TD>
|
||||
<TD VAlign="top"><code>range_size<X>::type</code></TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
<h3>Expression semantics </h3>
|
||||
|
||||
<table border="1" cellpadding="5">
|
||||
<TR>
|
||||
<TH>Expression</TH>
|
||||
<TH>Semantics</TH>
|
||||
<TH>Postcondition</TH>
|
||||
</TR>
|
||||
<tr>
|
||||
<TD VAlign="top"><code>size(a)</code></TD>
|
||||
<TD VAlign="top">Returns the size of the Range, that is, its number
|
||||
of elements. Note <code>size(a) == 0u</code> is equivalent to
|
||||
<code>empty(a).</code></TD>
|
||||
<TD VAlign="top"><code>size(a) >= 0</TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
<h3>Complexity guarantees</h3>
|
||||
|
||||
<p><code>size(a)</code> is at most amortized linear time.</p>
|
||||
|
||||
<h3>Invariants</h3>
|
||||
<p>
|
||||
<Table border="1" cellpadding="5">
|
||||
<TR>
|
||||
<TD VAlign="top">Range size</TD>
|
||||
<TD VAlign="top"><code>size(a)</code> is equal to the distance from <code>begin(a)</code>
|
||||
to <code>end(a)</code>.</TD> </table>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<a name=bidirectional_range><h2>Bidirectional Range</h2>
|
||||
|
||||
<h3>Notation</h3>
|
||||
<Table>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>X</code></TD>
|
||||
<TD VAlign="top">A type that is a model of Bidirectional Range.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top"><code>a</code></TD>
|
||||
<TD VAlign="top">Object of type <code>X</code>.</TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
<h3>Description</h3> This concept provides access to iterators that traverse in
|
||||
both directions (forward and reverse). The
|
||||
<code>range_iterator<X>::type</code> iterator must meet all of the requirements
|
||||
of <a
|
||||
href="../../iterator/doc/new-iter-concepts.html#bidirectional-traversal-iterator
|
||||
s-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterator.</a>
|
||||
|
||||
<h3>Refinement of</h3> <a href="#forward_range">Forward Range</a>
|
||||
|
||||
<h3>Associated types</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TD VAlign="top">Reverse Iterator type</TD>
|
||||
<TD VAlign="top"><code>range_reverse_iterator<X>::type</code></TD>
|
||||
<TD VAlign="top">The type of iterator used to iterate through a Range's elements
|
||||
in reverse order. The iterator's value type is expected to be the Range's value
|
||||
type. A conversion from the reverse iterator type to the const reverse iterator
|
||||
type must exist. </TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Const reverse iterator type</TD>
|
||||
<TD
|
||||
VAlign="top"><code>range_const_reverse_iterator<X>::type</code></TD>
|
||||
<TD VAlign="top">A type of reverse iterator that may be used to examine, but not
|
||||
to modify, a Range's elements.</TD>
|
||||
</TR>
|
||||
</table>
|
||||
|
||||
|
||||
<h3>Valid expressions</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Name</TH>
|
||||
<TH>Expression</TH>
|
||||
<TH>Return type</TH>
|
||||
<TH>Semantics</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Beginning of range</TD>
|
||||
<TD VAlign="top"><code>rbegin(a)</code></TD>
|
||||
<TD VAlign="top"><code>range_reverse_iterator<X>::type</code> if
|
||||
<code>a</code> is mutable, <code>range_const_reverse_iterator<X>::type</code>
|
||||
otherwise.</TD>
|
||||
<TD VAlign="top">Equivalent to
|
||||
<code>range_reverse_iterator<X>::type(end(a))</code>.</TD> </TR>
|
||||
<TR>
|
||||
<TD VAlign="top">End of range</TD>
|
||||
<TD VAlign="top"><code>rend(a)</code></TD>
|
||||
<TD VAlign="top"><code>range_reverse_iterator<X>::type</code> if
|
||||
<code>a</code> is mutable, <code>range_const_reverse_iterator<X>::type</code>
|
||||
otherwise.</TD>
|
||||
<TD VAlign="top">Equivalent to
|
||||
<code>range_reverse_iterator<X>::type(begin(a))</code>.</TD> </tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Complexity guarantees</h3>
|
||||
|
||||
<code>rbegin(a)</code> has the same complexity as <code>end(a)</code> and <code>rend(a)</code>
|
||||
has the same complexity as <code>begin(a)</code> from <a
|
||||
href="#forward_range">Forward Range</a>.
|
||||
|
||||
<h3>Invariants</h3>
|
||||
<p>
|
||||
<Table border="1" cellpadding="5">
|
||||
<TR>
|
||||
<TD VAlign="top">Valid reverse range</TD>
|
||||
<TD VAlign="top">For any Bidirectional Range <code>a</code>, <code>[rbegin(a),rend(a))</code>
|
||||
is a valid range, that is, <code>rend(a)</code> is reachable from <code>rbegin(a)</code>
|
||||
in a finite number of increments.</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign="top">Completeness</TD>
|
||||
<TD VAlign="top">An algorithm that iterates through the range <code>[rbegin(a),rend(a))</code>
|
||||
will pass through every element of <code>a</code>.</TD>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<a name=random_access_range><h2>Random Access Range</h2> <h3>Description</h3>
|
||||
<p>
|
||||
A range <code>X</code> where <code>range_iterator<X>::type</code> is a model
|
||||
of <a
|
||||
|
||||
href="../../iterator/doc/new-iter-concepts.html#random-access-traversal-iterators
|
||||
-lib-random-access-traversal-iterators">Random Access Traversal Iterator</a>
|
||||
</p>
|
||||
|
||||
<h3>Refinement of</h3>
|
||||
<p>
|
||||
<a href="#bidirectional_range">Bidirectional Range</a>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<!--
|
||||
<h3>Notes</h3>
|
||||
|
||||
|
||||
<P>
|
||||
<A name="1">[1]</A>
|
||||
|
||||
The reference type does not have to be a real C++ reference. The requirements of
|
||||
the reference type is that it <i>behaves</i> like a real reference. Hence the
|
||||
reference type must be convertible to the value_type and assignment through
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<HR>
|
||||
<br>
|
||||
-->
|
||||
|
||||
<TABLE>
|
||||
<TR valign="top">
|
||||
<TD nowrap>Copyright © 2000</TD>
|
||||
<TD><A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>
|
||||
</TR>
|
||||
<tr >
|
||||
<TD nowrap>Copyright © 2004</TD>
|
||||
<TD>Thorsten Ottosen.
|
||||
</TABLE>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
31
doc/style.css
Executable file
31
doc/style.css
Executable file
@ -0,0 +1,31 @@
|
||||
pre{
|
||||
BORDER-RIGHT: gray 1pt solid;
|
||||
PADDING-RIGHT: 2pt;
|
||||
BORDER-TOP: gray 1pt solid;
|
||||
DISPLAY: block;
|
||||
PADDING-LEFT: 2pt;
|
||||
PADDING-BOTTOM: 2pt;
|
||||
BORDER-LEFT: gray 1pt solid;
|
||||
MARGIN-RIGHT: 32pt;
|
||||
PADDING-TOP: 2pt;
|
||||
BORDER-BOTTOM: gray 1pt solid;
|
||||
FONT-FAMILY: "Courier New", Courier, mono;
|
||||
background-color: #EEEEEE;
|
||||
}
|
||||
|
||||
|
||||
.keyword{color: #0000FF;}
|
||||
.identifier{}
|
||||
.comment{font-style: italic; color: #008000;}
|
||||
.special{color: #800040;}
|
||||
.preprocessor{color: #3F007F;}
|
||||
.string{font-style: italic; color: #666666;}
|
||||
.literal{font-style: italic; color: #666666;}
|
||||
|
||||
table
|
||||
{
|
||||
cellpadding: 5px;
|
||||
border: 2px;
|
||||
}
|
||||
|
||||
|
126
doc/style.html
Executable file
126
doc/style.html
Executable file
@ -0,0 +1,126 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Terminology and Style Guidelines </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range </h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Terminology and style guidelines </h2>
|
||||
|
||||
<p>
|
||||
The use of a consistent terminology is as important for <a href="range.html#range">Range</a>s
|
||||
and range-based algorithms as it is for iterators and iterator-based algorithms.
|
||||
If a conventional set of names are adopted, we can avoid misunderstandings and
|
||||
write generic function prototypes that are <i>self-documenting</i>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since ranges are characterized by a specific underlying iterator type, we get a
|
||||
type of range for each type of iterator. Hence we can speak of the following
|
||||
types of ranges:
|
||||
<ul>
|
||||
<li>
|
||||
<i>Value access</i> category:
|
||||
<ul>
|
||||
<li>
|
||||
Readable Range
|
||||
<li>
|
||||
Writeable Range
|
||||
<li>
|
||||
Swappable Range
|
||||
<li>
|
||||
Lvalue Range
|
||||
</ul>
|
||||
<li>
|
||||
<i>Traversal</i> category:
|
||||
<ul>
|
||||
<li>
|
||||
<a href="range.html#single_pass_range">Single Pass Range</a>
|
||||
<li>
|
||||
<a href="range.html#forward_range">Forward Range</a>
|
||||
<li>
|
||||
<a href="range.html#bidirectional_range">Bidirectional Range</a> <li>
|
||||
<a href="range.html#random_access_range">Random Access Range</a> </ul>
|
||||
</ul>
|
||||
Notice how we have used the categories from the <a href=../../iterator/doc/new-iter-concepts.html>new
|
||||
style iterators</a>.
|
||||
|
||||
<p>
|
||||
Notice that an iterator (and therefore an range) has one <i>traversal</i>
|
||||
property and one or more properties from the <i>value access</i> category. So in
|
||||
reality we will mostly talk about mixtures such as
|
||||
<ul>
|
||||
<li>
|
||||
Random Access Readable Writeable Range
|
||||
<li>
|
||||
Forward Lvalue Range
|
||||
</ul>
|
||||
By convention, we should always specify the <i>traversal</i> property first as
|
||||
done above. This seems reasonable since there will only be one <i>traversal</i>
|
||||
property, but perhaps many <i>value access</i> properties.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It might, however, be reasonable to specify only one category if the other
|
||||
category does not matter. For example, the <a
|
||||
href="utility_class.html#iter_range">iterator_range</a> can be constructed from
|
||||
a Forward Range. This means that we do not care about what <i>value access</i>
|
||||
properties the Range has. Similarly, a Readable Range will be one that has the
|
||||
lowest possible <i>traversal</i> property (Single Pass).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As another example, consider how we specify the interface of <code>std::sort()</code>.
|
||||
Algorithms are usually more cumbersome to specify the interface of since both <i>traversal</i>
|
||||
and <i>value access</i> properties must be exactly defined. The iterator-based
|
||||
version looks like this:
|
||||
|
||||
<pre>
|
||||
<span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=special>>
|
||||
</span><span class=keyword>void </span><span class=identifier>sort</span><span class=special>( </span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=identifier>first</span><span class=special>,
|
||||
</span><span class=identifier>RandomAccessTraversalReadableWritableIterator </span><span class=identifier>last </span><span class=special>);</span>
|
||||
</pre>
|
||||
For ranges the interface becomes
|
||||
|
||||
<pre>
|
||||
<span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>RandomAccessReadableWritableRange </span><span class=special>>
|
||||
</span><span class=keyword>void </span><span class=identifier>sort</span><span class=special>( </span><span class=identifier>RandomAccessReadableWritableRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);</span>
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
352
doc/utility_class.html
Normal file
352
doc/utility_class.html
Normal file
@ -0,0 +1,352 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Utilities </title>
|
||||
<link rel="stylesheet" href="style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../../boost.png" border="0" ></td>
|
||||
<td ><h1 align="center">Boost.Range</h1></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Utilities</h2>
|
||||
<p>
|
||||
Having an abstraction that encapsulates a pair of iterators is very useful. The
|
||||
standard library uses <code>std::pair</code> in some circumstances, but that
|
||||
class is cumbersome to use because we need to specify two template arguments,
|
||||
and for all range algorithm purposes we must enforce the two template arguments
|
||||
to be the same. Moreover, <code>std::pair<iterator,iterator></code> is hardly
|
||||
self-documenting whereas more domain specific class names are. Therefore these
|
||||
two classes are provided:
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Class <a href=#iter_range><code>iterator_range</code></a>
|
||||
<li>
|
||||
Class <a href=#sub_range><code>sub_range</code></a>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
The <code>iterator_range</code> class is templated on an
|
||||
<a href="../../iterator/doc/new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators">Forward
|
||||
Traversal Iterator</a> and should be used whenever fairly general code is needed.
|
||||
The <code>sub_range</code> class is templated on an <a href="range.html#forward_range">Forward
|
||||
Range</a> and it is less general, but a bit easier to use since its template
|
||||
argument is easier to specify. The biggest difference is, however, that a
|
||||
<code>sub_range</code> can propagate constness because it knows what a
|
||||
corresponding <code>const_iterator</code> is. </p>
|
||||
|
||||
<p>
|
||||
Both classes can be used as ranges since they implement the <a
|
||||
href="boost_range.html#minimal_interface">minimal interface</a>
|
||||
required for this to work automatically.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<a name=iter_range></a> <h1>Class <code>iterator_range</code></h1>
|
||||
<p>
|
||||
The intention of the <code>iterator_range</code> class is to encapsulate two
|
||||
iterators so they fulfill the <a
|
||||
href="range.html#forward_range">Forward Range</a> concept. A few other
|
||||
functions are also provided for convenience.
|
||||
</p>
|
||||
<p>
|
||||
If the template argument is not a model of Forward Traversal Iterator, one can
|
||||
still use a subset of the interface. In particular, <code>size()</code> requires
|
||||
Forward Traversal Iterators whereas <code>empty()</code> only requires Single
|
||||
Pass Iterators.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Recall that many default constructed iterators
|
||||
are <i>singular</i> and hence can only be assigned, but not compared or
|
||||
incremented or anything. However, if one creates a default constructed
|
||||
<code>iterator_range</code>, then one
|
||||
can still call all its member functions. This means that the
|
||||
<code>iterator_range</code> will still be usable in many contexts even
|
||||
though the iterators underneath are not.
|
||||
</p>
|
||||
|
||||
<h3>Synopsis</h3>
|
||||
|
||||
<pre>
|
||||
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||
<span class=special>{
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||
</span><span class=keyword>class </span><span class=identifier>iterator_range
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// Forward Range types
|
||||
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>value_type</span><span class=special>;
|
||||
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>difference_type</span><span class=special>;
|
||||
</span><span class=keyword>typedef </span><span class=special>... </span><span class=identifier>size_type</span><span class=special>;
|
||||
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>iterator</span><span class=special>;
|
||||
</span><span class=keyword>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>const_iterator</span><span class=special>;
|
||||
|
||||
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator2 </span><span class=identifier>Begin</span><span class=special>, </span><span class=identifier>ForwardTraversalIterator2 </span><span class=identifier>End </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// Forward Range functions
|
||||
</span><span class=identifier>iterator </span><span class=identifier>begin</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
</span><span class=identifier>iterator </span><span class=identifier>end</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
</span><span class=identifier>size_type </span><span class=identifier>size</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
</span><span class=keyword>bool </span><span class=identifier>empty</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
|
||||
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// convenience
|
||||
</span><span class=keyword>operator </span><a
|
||||
href="#unspecified_bool"><span class=identifier>unspecified_bool_type</span></a><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
</span> <span class=keyword>bool</span> <span
|
||||
class=identifier><a href="#equal">equal</a></span><span
|
||||
class=special>( </span><span class=keyword>const <span
|
||||
class=identifier>iterator_range</span><span class=special>& ) </span><span
|
||||
class=keyword>const;</span>
|
||||
|
||||
</span><span class=special>};
|
||||
|
||||
</span><span class=comment>// stream output
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>Traits </span><span class=special>>
|
||||
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>>&
|
||||
</span><span class=keyword>operator</span><span class=special><<( </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>basic_ostream</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Traits</span><span class=special>>& </span><span class=identifier>Os</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=comment>// <a href="#comparison">comparison</a>
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>==( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>==( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>==( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>!=( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>!=( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>!=( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special><( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator2</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special><( </span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special><( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>l</span><span class=special>,
|
||||
</span><span class=keyword>const </span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>ForwardTraversalIterator</span><span class=special>>& </span><span class=identifier>r </span><span class=special>);</span>
|
||||
|
||||
</span><span class=comment>// external construction
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>Begin</span><span class=special>,
|
||||
</span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>End </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>iterator_range</span><span class=special>< </span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=comment>// convenience
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>Sequence</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=identifier>Sequence </span><a href="#copy_range"><span
|
||||
class=identifier>copy_range</span></a><span class=special>( </span><span
|
||||
class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>Sequence</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>ForwardRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>Func </span><span class=special>>
|
||||
</span><span class=identifier>Sequence </span><a
|
||||
href="#transform_range"><span
|
||||
class=identifier>transform_range</span></a><span class=special>( </span><span
|
||||
class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>& </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>Func </span><span class=identifier>func </span><span class=special>);
|
||||
</span>
|
||||
<span class=special>} </span><span class=comment>// namespace 'boost'</span>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If an instance of
|
||||
<code>iterator_range</code> is constructed by a client with two iterators, the
|
||||
client must ensure that the two iterators delimit a valid closed-open range
|
||||
<code>[begin,end)</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is worth noticing that the templated constructors and assignment operators
|
||||
allow conversion from <code>iterator_range<iterator></code> to
|
||||
<code>iterator_range<const_iterator></code>. Similarly, since the comparison
|
||||
operators have two template arguments, we can compare ranges whenever the
|
||||
iterators are comparable; for example when we are dealing with const and
|
||||
non-const iterators from the same container. </p>
|
||||
|
||||
<h3>Details member functions</h3>
|
||||
|
||||
<p>
|
||||
<a name="unspecified_bool"></a>
|
||||
<code>operator unspecified_bool_type() const; </code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>!empty();</code>
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a name="equal"></a>
|
||||
<code>bool equal( iterator_range& r ) const;</code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>begin() == r.begin() && end() == r.end();</code>
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<h3>Details functions</h3>
|
||||
|
||||
<p>
|
||||
<a name="comparison"></a>
|
||||
<code>bool operator==( const ForwardRange1& l, const ForwardRange2& r );</code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>size(l) != size(r) ? false : std::equal( begin(l), end(l), begin(r) );</code> </blockquote> </p>
|
||||
<code>bool operator!=( const ForwardRange1& l, const ForwardRange2& r );</code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>!( l == r );</code>
|
||||
</blockquote>
|
||||
<code>bool operator<( const ForwardRange1& l, const ForwardRange2& r );</code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>std::lexicographical_compare( begin(l), end(l), begin(r), end(r) );</code> </blockquote>
|
||||
<p>
|
||||
<a name="copy_range"></a>
|
||||
<code>Sequence copy_range( const ForwardRange& r );</code>
|
||||
<blockquote>
|
||||
<i>Returns</i> <code>Sequence( begin(r), end(r) );</code>
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a name="transform_range"></a>
|
||||
<code>Sequence transform_range( const ForwardRange& r, Func func );</code>
|
||||
<blockquote>
|
||||
<i>Effects</i> <br>
|
||||
<code>Sequence seq;</code> <br>
|
||||
<code>std::transform( begin(r), end(r), std::back_inserter(seq), func );</code>
|
||||
<br>
|
||||
<code>return seq;</code>
|
||||
</blockquote>
|
||||
</p>
|
||||
|
||||
<hr> <a name=sub_range></a>
|
||||
<h1>Class <code>sub_range</code></h1>
|
||||
|
||||
The <code>sub_range</code> class inherits all its functionality
|
||||
from the <a href="#iter_range"><code>iterator_range</code></a> class.
|
||||
The <code>sub_range</code> class is often easier to use because
|
||||
one must specify the <a href="range.html#forward_range">Forward Range</a>
|
||||
template argument instead of an iterator. Moreover, the <code>sub_range</code>
|
||||
class can propagate constness since it knows what a corresponding
|
||||
<code>const_iterator</code> is.
|
||||
|
||||
<h3>Synopsis</h3>
|
||||
|
||||
<pre>
|
||||
<span class=keyword>namespace </span><span class=identifier>boost</span>
|
||||
<span class=special>{
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>>
|
||||
</span><span class=keyword>class </span><span class=identifier>sub_range </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>iterator_range</span><span class=special>< </span><span class=keyword>typename </span><span class=identifier>range_result_iterator</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=special>>
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>public</span><span class=special>: </span>
|
||||
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_result_iterator</span><span class=special><</span><span class=identifier>ForwardRange</span><spanclass=special>>::</span><span class=identifier>type </span><span class=identifier>iterator</span><span class=special>;</span>
|
||||
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special><</span><span class=identifier>ForwardRange</span><span class=special>>::</span><span class=identifier>type </span><span class=identifier>const_iterator</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>>
|
||||
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>Begin</span><span class=special>, </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>End </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardRange2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>Range2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||
</span><span class=identifier>sub_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
|
||||
</span><span class=keyword>template</span><span class=special>< </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>>
|
||||
</span><span class=identifier>sub_range</span><span class=special>& </span><span class=keyword>operator</span><span class=special>=( </span><span class=keyword>const </span><span class=identifier>ForwardRange2</span><span class=special>& </span><span class=identifier>r </span><span class=special>);
|
||||
</span>
|
||||
<span class=keyword>public</span><span class=special>:
|
||||
</span><span class=identifier>iterator </span><span
|
||||
class=identifier>begin</span><span class=special>();
|
||||
</span><span class=identifier>const_iterator </span><span class=identifier>begin</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
|
||||
</span><span class=identifier>iterator </span><span class=identifier>end</span><span class=special>();
|
||||
</span><span class=identifier>const_iterator </span><span class=identifier>end</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>public</span><span class=special>:
|
||||
</span><span class=comment>// rest of interface inherited from iterator_range
|
||||
</span><span class=special>};
|
||||
</span>
|
||||
<span class=special>} </span><span class=comment>// namespace 'boost'</span>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The class should be trivial to use as seen below.
|
||||
Imagine that we have an algorithm that searches for a sub-string in a string.
|
||||
The
|
||||
result is an <code>iterator_range</code>, that delimits the match. We need to
|
||||
store the result
|
||||
from this algorithm. Here is an example of how we can do it with and without
|
||||
<code>sub_range</code>
|
||||
<pre>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>str</span><span class=special>(</span><span class=string>"hello"</span><span class=special>);
|
||||
</span><span class=identifier>iterator_range</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>> </span><span class=identifier>ir </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>"ll" </span><span class=special>);
|
||||
</span><span class=identifier>sub_range</span><span class=special><</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>> </span><span class=identifier>sub </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>"ll" </span><span class=special>);</span>
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -8,15 +8,15 @@
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
|
||||
#ifndef BOOST_RANGE_HPP
|
||||
#define BOOST_RANGE_HPP
|
||||
#ifndef BOOST_RANGE_HPP_27_07_04
|
||||
#define BOOST_RANGE_HPP_27_07_04
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/range/functions.hpp>
|
||||
#include <boost/range/types.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/sub_range.hpp>
|
||||
|
||||
|
@ -26,22 +26,22 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
// primary template
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME const_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type
|
||||
begin( const C& c )
|
||||
{
|
||||
return c.begin();
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
|
||||
begin( C& c )
|
||||
{
|
||||
return c.begin();
|
||||
@ -83,33 +83,93 @@ namespace range
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x3204 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// CW up to 9.3 and borland have troubles with function ordering
|
||||
inline const char* begin( const char* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline char* begin( char* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline const wchar_t* begin( const wchar_t* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline wchar_t* begin( wchar_t* s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
#else
|
||||
inline const char* begin( const char*& s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
inline char* begin( char*& s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
inline const wchar_t* begin( const wchar_t*& s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
inline wchar_t* begin( wchar_t*& s )
|
||||
{
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace 'range'
|
||||
} // namespace 'range_detail'
|
||||
|
||||
using range::begin;
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
|
||||
{
|
||||
return range_detail::begin( r );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type begin( const T& r )
|
||||
{
|
||||
return range_detail::begin( r );
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 3003 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// BCB and CW are not able to overload pointer when class overloads are also available.
|
||||
template<>
|
||||
inline range_const_iterator<const char*>::type begin<const char*>( const char*& r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline range_const_iterator<const wchar_t*>::type begin<const wchar_t*>( const wchar_t*& r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type
|
||||
const_begin( const T& r )
|
||||
{
|
||||
return begin( r );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -11,35 +11,37 @@
|
||||
#ifndef BOOST_RANGE_CONFIG_HPP
|
||||
#define BOOST_RANGE_CONFIG_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_CT_DEDUCED_TYPENAME
|
||||
#ifdef BOOST_RANGE_DEDUCED_TYPENAME
|
||||
#error "macro already defined!"
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#define BOOST_CT_DEDUCED_TYPENAME
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
#define BOOST_RANGE_DEDUCED_TYPENAME
|
||||
#else
|
||||
#define BOOST_CT_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
|
||||
#define BOOST_RANGE_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_CT_NO_ARRAY_SUPPORT
|
||||
#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
|
||||
#error "macro already defined!"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER <= 1200 && !defined( __COMO__ ) && !defined( _GNUC_ )
|
||||
#define BOOST_CT_NO_ARRAY_SUPPORT
|
||||
#if _MSC_VER <= 1200 && !defined( __COMO__ ) && !defined( __GNUC__ ) && __MWERKS__ <= 0x3003
|
||||
#define BOOST_RANGE_NO_ARRAY_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_CT_NO_ARRAY_SUPPORT
|
||||
#define BOOST_ARRAY_REF (array)
|
||||
#define BOOST_CT_NO_STATIC_ASSERT
|
||||
#ifdef BOOST_RANGE_NO_ARRAY_SUPPORT
|
||||
#define BOOST_RANGE_ARRAY_REF() (array)
|
||||
#define BOOST_RANGE_NO_STATIC_ASSERT
|
||||
#else
|
||||
#define BOOST_ARRAY_REF (&array)
|
||||
#define BOOST_RANGE_ARRAY_REF() (&array)
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct const_iterator_of
|
||||
struct range_const_iterator
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::const_iterator type;
|
||||
};
|
||||
@ -41,13 +41,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Iterator >
|
||||
struct const_iterator_of< std::pair<Iterator,Iterator> >
|
||||
struct range_const_iterator< std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
struct const_iterator_of< const std::pair<Iterator,Iterator> >
|
||||
struct range_const_iterator< const std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
@ -57,13 +57,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct const_iterator_of< T[sz] >
|
||||
struct range_const_iterator< T[sz] >
|
||||
{
|
||||
typedef const T* type;
|
||||
};
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct const_iterator_of< const T[sz] >
|
||||
struct range_const_iterator< const T[sz] >
|
||||
{
|
||||
typedef const T* type;
|
||||
};
|
||||
@ -73,25 +73,25 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct const_iterator_of< char* >
|
||||
struct range_const_iterator< char* >
|
||||
{
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct const_iterator_of< wchar_t* >
|
||||
struct range_const_iterator< wchar_t* >
|
||||
{
|
||||
typedef const wchar_t* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct const_iterator_of< const char* >
|
||||
struct range_const_iterator< const char* >
|
||||
{
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct const_iterator_of< const wchar_t* >
|
||||
struct range_const_iterator< const wchar_t* >
|
||||
{
|
||||
typedef const wchar_t* type;
|
||||
};
|
||||
|
@ -26,10 +26,10 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct const_reverse_iterator_of
|
||||
struct range_const_reverse_iterator
|
||||
{
|
||||
typedef reverse_iterator<
|
||||
BOOST_DEDUCED_TYPENAME const_iterator_of<C>::type > type;
|
||||
BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type > type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
@ -30,7 +30,7 @@ namespace boost
|
||||
struct range_begin<std_container_>
|
||||
{
|
||||
template< typename C >
|
||||
static BOOST_CT_DEDUCED_TYPENAME result_iterator_of<C>::type fun( C& c )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<C>::type fun( C& c )
|
||||
{
|
||||
return c.begin();
|
||||
};
|
||||
@ -44,7 +44,7 @@ namespace boost
|
||||
struct range_begin<std_pair_>
|
||||
{
|
||||
template< typename P >
|
||||
static BOOST_CT_DEDUCED_TYPENAME result_iterator_of<P>::type fun( const P& p )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<P>::type fun( const P& p )
|
||||
{
|
||||
return p.first;
|
||||
}
|
||||
@ -105,13 +105,13 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace 'range_traits_detail'
|
||||
} // namespace 'range_detail'
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME result_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_result_iterator<C>::type
|
||||
begin( C& c )
|
||||
{
|
||||
return range_traits_detail::range_begin< BOOST_DEDUCED_TYPENAME range_traits_detail::range<C>::type >::fun( c );
|
||||
return range_detail::range_begin< BOOST_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include <boost/range/config.hpp>
|
||||
#include <boost/range/detail/sfinae.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/detail/ice_or.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
@ -59,7 +58,7 @@ namespace boost
|
||||
typedef mpl::int_<12>::type string_;
|
||||
|
||||
template< typename C >
|
||||
struct collection_helper
|
||||
struct range_helper
|
||||
{
|
||||
static C* c;
|
||||
static C ptr;
|
||||
@ -79,35 +78,35 @@ namespace boost
|
||||
template< typename C >
|
||||
class range
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_pair_,
|
||||
boost::range_detail::std_pair_,
|
||||
void >::type pair_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_array_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_pair_,
|
||||
boost::range_detail::std_pair_,
|
||||
void >::type pair_t;
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_array_,
|
||||
boost::range_detail::array_,
|
||||
pair_t >::type array_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_string_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_string_,
|
||||
boost::range_detail::string_,
|
||||
array_t >::type string_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_const_char_ptr_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_const_char_ptr_,
|
||||
boost::range_detail::const_char_ptr_,
|
||||
string_t >::type const_char_ptr_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_char_ptr_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_char_ptr_,
|
||||
boost::range_detail::char_ptr_,
|
||||
const_char_ptr_t >::type char_ptr_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_const_wchar_t_ptr_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_const_wchar_t_ptr_,
|
||||
boost::range_detail::const_wchar_t_ptr_,
|
||||
char_ptr_t >::type const_wchar_ptr_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_wchar_t_ptr_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_wchar_t_ptr_,
|
||||
boost::range_detail::wchar_t_ptr_,
|
||||
const_wchar_ptr_t >::type wchar_ptr_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_wchar_t_array_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_wchar_t_array_,
|
||||
boost::range_detail::wchar_t_array_,
|
||||
wchar_ptr_t >::type wchar_array_t;
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::collection_helper<C>::is_char_array_,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::range_detail::range_helper<C>::is_char_array_,
|
||||
boost::range_detail::char_array_,
|
||||
wchar_array_t >::type char_array_t;
|
||||
public:
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< boost::is_void<char_array_t>::value,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< boost::is_void<char_array_t>::value,
|
||||
boost::range_detail::std_container_,
|
||||
char_array_t >::type type;
|
||||
}; // class 'range'
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define BOOST_RANGE_DETAIL_CONST_ITERATOR_HPP
|
||||
|
||||
#include <boost/range/detail/common.hpp>
|
||||
#include <boost/type_traits/remove_bounds.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// missing partial specialization workaround.
|
||||
@ -44,8 +45,28 @@ namespace boost
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct range_const_iterator_<array_>; // give up
|
||||
struct range_const_iterator_<array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef const BOOST_RANGE_DEDUCED_TYPENAME
|
||||
remove_bounds<T>::type* type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_const_iterator_<char_array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef const BOOST_RANGE_DEDUCED_TYPENAME
|
||||
remove_bounds<T>::type* type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_const_iterator_<char_ptr_>
|
||||
@ -90,7 +111,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
class const_iterator_of
|
||||
class range_const_iterator
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
public:
|
||||
|
@ -41,7 +41,7 @@ namespace boost
|
||||
template< typename P >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::iterator_difference< BOOST_DEDUCED_TYPENAME P::first_type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
@ -55,6 +55,16 @@ namespace boost
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_difference_type_<char_array_>
|
||||
{
|
||||
template< typename A >
|
||||
struct pts
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_difference_type_<char_ptr_>
|
||||
{
|
||||
@ -98,11 +108,11 @@ namespace boost
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
class difference_type_of
|
||||
class range_difference
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
public:
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME range_detail::range_difference_type_<c_type>::BOOST_NESTED_TEMPLATE pts<C>::type type;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,14 +18,14 @@ namespace boost
|
||||
namespace range_detail
|
||||
{
|
||||
template< typename T >
|
||||
struct collection_empty;
|
||||
struct range_empty;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_empty<std_container_>
|
||||
struct range_empty<std_container_>
|
||||
{
|
||||
template< typename C >
|
||||
static bool fun( C& c )
|
||||
@ -39,7 +39,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_empty<std_pair_>
|
||||
struct range_empty<std_pair_>
|
||||
{
|
||||
template< typename P >
|
||||
static bool fun( const P& p )
|
||||
@ -53,7 +53,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_empty<array_>
|
||||
struct range_empty<array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static bool fun( T BOOST_ARRAY_REF[sz] )
|
||||
@ -69,7 +69,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_empty<char_ptr_>
|
||||
struct range_empty<char_ptr_>
|
||||
{
|
||||
static bool fun( const char* s )
|
||||
{
|
||||
@ -78,7 +78,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_empty<const_char_ptr_>
|
||||
struct range_empty<const_char_ptr_>
|
||||
{
|
||||
static bool fun( const char* s )
|
||||
{
|
||||
@ -87,7 +87,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_empty<wchar_t_ptr_>
|
||||
struct range_empty<wchar_t_ptr_>
|
||||
{
|
||||
static bool fun( const wchar_t* s )
|
||||
{
|
||||
@ -96,7 +96,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_empty<const_wchar_t_ptr_>
|
||||
struct range_empty<const_wchar_t_ptr_>
|
||||
{
|
||||
static bool fun( const wchar_t* s )
|
||||
{
|
||||
@ -111,7 +111,7 @@ namespace boost
|
||||
inline bool
|
||||
empty( const C& c )
|
||||
{
|
||||
return range_detail::collection_empty< BOOST_CT_DEDUCED_TYPENAME range_detail::collection<C>::type >::fun( c );
|
||||
return range_detail::range_empty< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
@ -20,17 +20,18 @@ namespace boost
|
||||
namespace range_detail
|
||||
{
|
||||
template< typename T >
|
||||
struct collection_end;
|
||||
struct range_end;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_end<std_container_>
|
||||
struct range_end<std_container_>
|
||||
{
|
||||
template< typename C >
|
||||
static BOOST_CT_DEDUCED_TYPENAME result_iterator_of<C>::type fun( C& c )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<C>::type
|
||||
fun( C& c )
|
||||
{
|
||||
return c.end();
|
||||
};
|
||||
@ -41,10 +42,11 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_end<std_pair_>
|
||||
struct range_end<std_pair_>
|
||||
{
|
||||
template< typename P >
|
||||
static BOOST_CT_DEDUCED_TYPENAME result_iterator_of<P>::type fun( const P& p )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME range_result_iterator<P>::type
|
||||
fun( const P& p )
|
||||
{
|
||||
return p.second;
|
||||
}
|
||||
@ -55,10 +57,10 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_end<array_>
|
||||
struct range_end<array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static T* fun( T BOOST_ARRAY_REF[sz] )
|
||||
static T* fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return boost::range_detail::array_end( array );
|
||||
}
|
||||
@ -66,20 +68,20 @@ namespace boost
|
||||
|
||||
|
||||
template<>
|
||||
struct collection_end<char_array_>
|
||||
struct range_end<char_array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static std::size_t fun( T BOOST_ARRAY_REF[sz] )
|
||||
static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return boost::range_detail::array_end( array );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_end<wchar_t_array_>
|
||||
struct range_end<wchar_t_array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static std::size_t fun( T BOOST_ARRAY_REF[sz] )
|
||||
static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return boost::range_detail::array_end( array );
|
||||
}
|
||||
@ -90,7 +92,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_end<char_ptr_>
|
||||
struct range_end<char_ptr_>
|
||||
{
|
||||
static char* fun( char* s )
|
||||
{
|
||||
@ -99,7 +101,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_end<const_char_ptr_>
|
||||
struct range_end<const_char_ptr_>
|
||||
{
|
||||
static const char* fun( const char* s )
|
||||
{
|
||||
@ -108,7 +110,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_end<wchar_t_ptr_>
|
||||
struct range_end<wchar_t_ptr_>
|
||||
{
|
||||
static wchar_t* fun( wchar_t* s )
|
||||
{
|
||||
@ -118,7 +120,7 @@ namespace boost
|
||||
|
||||
|
||||
template<>
|
||||
struct collection_end<const_wchar_t_ptr_>
|
||||
struct range_end<const_wchar_t_ptr_>
|
||||
{
|
||||
static const wchar_t* fun( const wchar_t* s )
|
||||
{
|
||||
@ -129,10 +131,10 @@ namespace boost
|
||||
} // namespace 'range_detail'
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME result_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_result_iterator<C>::type
|
||||
end( C& c )
|
||||
{
|
||||
return range_detail::collection_end< BOOST_DEDUCED_TYPENAME range_detail::collection<C>::type >::fun( c );
|
||||
return range_detail::range_end< BOOST_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
@ -51,50 +51,50 @@ namespace boost
|
||||
}
|
||||
#endif
|
||||
|
||||
template< typename Char >
|
||||
template< class Char >
|
||||
inline Char* str_end( Char* s )
|
||||
{
|
||||
return (Char*)str_end( s, s );
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline T* array_end( T (&array)[sz], int )
|
||||
|
||||
template< class T, std::size_t sz >
|
||||
inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz], int )
|
||||
{
|
||||
return array + sz;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline const T* array_end( const T (&array)[sz], int )
|
||||
template< class T, std::size_t sz >
|
||||
inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz], int )
|
||||
{
|
||||
return array + sz;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline T* array_end( T (&array)[sz], char_or_wchar_t_array_tag )
|
||||
template< class T, std::size_t sz >
|
||||
inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz], char_or_wchar_t_array_tag )
|
||||
{
|
||||
return array + sz - 1;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline const T* array_end( const T (&array)[sz], char_or_wchar_t_array_tag )
|
||||
template< class T, std::size_t sz >
|
||||
inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz], char_or_wchar_t_array_tag )
|
||||
{
|
||||
return array + sz - 1;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline T* array_end( T (&array)[sz] )
|
||||
template< class T, std::size_t sz >
|
||||
inline T* array_end( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
char_or_wchar_t_array_tag,
|
||||
int >::type tag;
|
||||
|
||||
return array_end<T,sz>( array, tag() );
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline const T* array_end( const T (&array)[sz] )
|
||||
template< class T, std::size_t sz >
|
||||
inline const T* array_end( const T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
char_or_wchar_t_array_tag,
|
||||
int >::type tag;
|
||||
|
||||
@ -105,49 +105,50 @@ namespace boost
|
||||
// size() help
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Char >
|
||||
inline std::size_t str_size( const Char* s )
|
||||
template< class Char >
|
||||
inline std::size_t str_size( const Char* const& s )
|
||||
{
|
||||
return str_end( s ) - s;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( T BOOST_ARRAY_REF[sz], int )
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz], int )
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( const T BOOST_ARRAY_REF[sz], int )
|
||||
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz], int )
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( T BOOST_ARRAY_REF[sz], char_or_wchar_t_array_tag )
|
||||
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz], char_or_wchar_t_array_tag )
|
||||
{
|
||||
return sz - 1;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( const T BOOST_ARRAY_REF[sz], char_or_wchar_t_array_tag )
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz], char_or_wchar_t_array_tag )
|
||||
{
|
||||
return sz - 1;
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( T (&array)[sz] )
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< is_same<const char,T>::value || is_same<const wchar_t,T>::value ||
|
||||
is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
char_or_wchar_t_array_tag,
|
||||
int >::type tag;
|
||||
return array_size<T,sz>( array, tag() );
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t array_size( const T (&array)[sz] )
|
||||
template< class T, std::size_t sz >
|
||||
inline std::size_t array_size( const T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME boost::mpl::if_c< is_same<char,T>::value || is_same<wchar_t,T>::value,
|
||||
char_or_wchar_t_array_tag,
|
||||
int >::type tag;
|
||||
return array_size<T,sz>( array, tag() );
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define BOOST_RANGE_DETAIL_ITERATOR_HPP
|
||||
|
||||
#include <boost/range/detail/common.hpp>
|
||||
#include <boost/type_traits/remove_bounds.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// missing partial specialization workaround.
|
||||
@ -45,7 +46,26 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator_<array_>; // give up
|
||||
struct range_iterator_<array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME
|
||||
remove_bounds<T>::type* type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator_<char_array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME
|
||||
remove_bounds<T>::type* type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator_<char_ptr_>
|
||||
@ -90,7 +110,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
class iterator_of
|
||||
class range_iterator
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
public:
|
||||
|
@ -28,32 +28,32 @@ namespace boost
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
yes_type is_string_impl( const char* );
|
||||
yes_type is_string_impl( const wchar_t* );
|
||||
yes_type is_string_impl( const char* const );
|
||||
yes_type is_string_impl( const wchar_t* const );
|
||||
no_type is_string_impl( ... );
|
||||
|
||||
template< std::size_t sz >
|
||||
yes_type is_char_array_impl( char BOOST_ARRAY_REF[sz] );
|
||||
yes_type is_char_array_impl( char BOOST_RANGE_ARRAY_REF()[sz] );
|
||||
template< std::size_t sz >
|
||||
yes_type is_char_array_impl( const char BOOST_ARRAY_REF[sz] );
|
||||
yes_type is_char_array_impl( const char BOOST_RANGE_ARRAY_REF()[sz] );
|
||||
no_type is_char_array_impl( ... );
|
||||
|
||||
template< std::size_t sz >
|
||||
yes_type is_wchar_t_array_impl( wchar_t BOOST_ARRAY_REF[sz] );
|
||||
yes_type is_wchar_t_array_impl( wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
|
||||
template< std::size_t sz >
|
||||
yes_type is_wchar_t_array_impl( const wchar_t BOOST_ARRAY_REFx[sz] );
|
||||
yes_type is_wchar_t_array_impl( const wchar_t BOOST_RANGE_ARRAY_REF()[sz] );
|
||||
no_type is_wchar_t_array_impl( ... );
|
||||
|
||||
yes_type is_char_ptr_impl( char* );
|
||||
yes_type is_char_ptr_impl( char* const );
|
||||
no_type is_char_ptr_impl( ... );
|
||||
|
||||
yes_type is_const_char_ptr_impl( const char* );
|
||||
yes_type is_const_char_ptr_impl( const char* const );
|
||||
no_type is_const_char_ptr_impl( ... );
|
||||
|
||||
yes_type is_wchar_t_ptr_impl( wchar_t* );
|
||||
yes_type is_wchar_t_ptr_impl( wchar_t* const );
|
||||
no_type is_wchar_t_ptr_impl( ... );
|
||||
|
||||
yes_type is_const_wchar_t_ptr_impl( const wchar_t* );
|
||||
yes_type is_const_wchar_t_ptr_impl( const wchar_t* const );
|
||||
no_type is_const_wchar_t_ptr_impl( ... );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,17 +22,17 @@ namespace boost
|
||||
namespace range_detail
|
||||
{
|
||||
template< typename T >
|
||||
struct collection_size;
|
||||
struct range_size_;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_size<std_container_>
|
||||
struct range_size_<std_container_>
|
||||
{
|
||||
template< typename C >
|
||||
static BOOST_CT_DEDUCED_TYPENAME C::size_type fun( const C& c )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME C::size_type fun( const C& c )
|
||||
{
|
||||
return c.size();
|
||||
};
|
||||
@ -43,10 +43,11 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_size<std_pair_>
|
||||
struct range_size_<std_pair_>
|
||||
{
|
||||
template< typename P >
|
||||
static BOOST_CT_DEDUCED_TYPENAME size_type_of<P>::type fun( const P& p )
|
||||
static BOOST_RANGE_DEDUCED_TYPENAME range_size<P>::type
|
||||
fun( const P& p )
|
||||
{
|
||||
return std::distance( p.first, p.second );
|
||||
}
|
||||
@ -57,30 +58,30 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_size<array_>
|
||||
struct range_size_<array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static std::size_t fun( T BOOST_ARRAY_REF[sz] )
|
||||
static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return sz;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_size<char_array_>
|
||||
struct range_size_<char_array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static std::size_t fun( T BOOST_ARRAY_REF[sz] )
|
||||
static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return boost::range_detail::array_size( array );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_size<wchar_t_array_>
|
||||
struct range_size_<wchar_t_array_>
|
||||
{
|
||||
template< typename T, std::size_t sz >
|
||||
static std::size_t fun( T BOOST_ARRAY_REF[sz] )
|
||||
static std::size_t fun( T BOOST_RANGE_ARRAY_REF()[sz] )
|
||||
{
|
||||
return boost::range_detail::array_size( array );
|
||||
}
|
||||
@ -91,7 +92,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct collection_size<char_ptr_>
|
||||
struct range_size_<char_ptr_>
|
||||
{
|
||||
static std::size_t fun( const char* s )
|
||||
{
|
||||
@ -100,7 +101,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_size<const_char_ptr_>
|
||||
struct range_size_<const_char_ptr_>
|
||||
{
|
||||
static std::size_t fun( const char* s )
|
||||
{
|
||||
@ -109,7 +110,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_size<wchar_t_ptr_>
|
||||
struct range_size_<wchar_t_ptr_>
|
||||
{
|
||||
static std::size_t fun( const wchar_t* s )
|
||||
{
|
||||
@ -118,7 +119,7 @@ namespace boost
|
||||
};
|
||||
|
||||
template<>
|
||||
struct collection_size<const_wchar_t_ptr_>
|
||||
struct range_size_<const_wchar_t_ptr_>
|
||||
{
|
||||
static std::size_t fun( const wchar_t* s )
|
||||
{
|
||||
@ -130,10 +131,10 @@ namespace boost
|
||||
|
||||
|
||||
template< typename C >
|
||||
BOOST_CT_DEDUCED_TYPENAME size_type_of<C>::type
|
||||
BOOST_RANGE_DEDUCED_TYPENAME range_size<C>::type
|
||||
size( const C& c )
|
||||
{
|
||||
return range_detail::collection_size< BOOST_CT_DEDUCED_TYPENAME range_detail::collection<C>::type >::fun( c );
|
||||
return range_detail::range_size_< BOOST_RANGE_DEDUCED_TYPENAME range_detail::range<C>::type >::fun( c );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
@ -54,6 +54,16 @@ namespace boost
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_size_type_<char_array_>
|
||||
{
|
||||
template< typename A >
|
||||
struct pts
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_size_type_<char_ptr_>
|
||||
{
|
||||
@ -92,12 +102,11 @@ namespace boost
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
class size_type_of
|
||||
class range_size
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
public:
|
||||
|
@ -26,11 +26,11 @@ namespace boost
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
char&
|
||||
sizer( const T BOOST_ARRAY_REF[sz] )[sz];
|
||||
sizer( const T BOOST_RANGE_ARRAY_REF()[sz] )[sz];
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
char&
|
||||
sizer( T BOOST_ARRAY_REF[sz] )[sz];
|
||||
sizer( T BOOST_RANGE_ARRAY_REF()[sz] )[sz];
|
||||
|
||||
} // namespace 'boost'
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define BOOST_RANGE_DETAIL_VALUE_TYPE_HPP
|
||||
|
||||
#include <boost/range/detail/common.hpp>
|
||||
#include <boost/type_traits/remove_bounds.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -41,12 +42,29 @@ namespace boost
|
||||
template< typename P >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value< BOOST_CT_DEDUCED_TYPENAME P::first_type >::type type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value< BOOST_RANGE_DEDUCED_TYPENAME P::first_type >::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_value_type_<array_>; // give up
|
||||
struct range_value_type_<array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_bounds<T>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_value_type_<char_array_>
|
||||
{
|
||||
template< typename T >
|
||||
struct pts
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_value_type_<char_ptr_>
|
||||
@ -91,7 +109,7 @@ namespace boost
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
class value_type_of
|
||||
class range_value
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_detail::range<C>::type c_type;
|
||||
public:
|
||||
|
@ -32,7 +32,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct difference_type_of
|
||||
struct range_difference
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::difference_type type;
|
||||
};
|
||||
@ -42,14 +42,14 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Iterator >
|
||||
struct difference_type_of< std::pair<Iterator,Iterator> >
|
||||
struct range_difference< std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_difference<Iterator>::type type;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
struct difference_type_of< const std::pair<Iterator,Iterator> >
|
||||
struct range_difference< const std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_difference<Iterator>::type type;
|
||||
@ -61,13 +61,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct difference_type_of< T[sz] >
|
||||
struct range_difference< T[sz] >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct difference_type_of< const T[sz] >
|
||||
struct range_difference< const T[sz] >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
@ -77,25 +77,25 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct difference_type_of< char* >
|
||||
struct range_difference< char* >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct difference_type_of< wchar_t* >
|
||||
struct range_difference< wchar_t* >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct difference_type_of< const char* >
|
||||
struct range_difference< const char* >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct difference_type_of< const wchar_t* >
|
||||
struct range_difference< const wchar_t* >
|
||||
{
|
||||
typedef std::ptrdiff_t type;
|
||||
};
|
||||
|
@ -16,47 +16,52 @@
|
||||
#endif
|
||||
|
||||
#include <boost/range/config.hpp>
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
#include <boost/range/detail/empty.hpp>
|
||||
#else
|
||||
//#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
//#include <boost/range/detail/empty.hpp>
|
||||
//#else
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
// primary template
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
inline bool empty( const C& c )
|
||||
{
|
||||
return begin( c ) == end( c );
|
||||
return boost::begin( c ) == boost::end( c );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool empty( const char* s )
|
||||
inline bool empty( const char* const& s )
|
||||
{
|
||||
return s == 0 || s[0] == 0;
|
||||
}
|
||||
|
||||
inline bool empty( const wchar_t* s )
|
||||
inline bool empty( const wchar_t* const& s )
|
||||
{
|
||||
return s == 0 || s[0] == 0;
|
||||
}
|
||||
|
||||
} // namespace 'range'
|
||||
} // namespace 'range_detail'
|
||||
|
||||
using range::empty;
|
||||
template< class T >
|
||||
inline bool empty( const T& r )
|
||||
{
|
||||
return range_detail::empty( r );
|
||||
}
|
||||
|
||||
} // namepace 'boost'
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
//#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
#endif
|
||||
|
@ -27,22 +27,22 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
// primary template
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME const_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type
|
||||
end( const C& c )
|
||||
{
|
||||
return c.end();
|
||||
}
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_DEDUCED_TYPENAME iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<C>::type
|
||||
end( C& c )
|
||||
{
|
||||
return c.end();
|
||||
@ -71,19 +71,21 @@ namespace range
|
||||
template< typename T, std::size_t sz >
|
||||
inline const T* end( const T (&array)[sz] )
|
||||
{
|
||||
return range_detail::array_end( array );
|
||||
return range_detail::array_end<T,sz>( array );
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline T* end( T (&array)[sz] )
|
||||
{
|
||||
return range_detail::array_end( array );
|
||||
return range_detail::array_end<T,sz>( array );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x3204 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// CW up to 9.3 and borland have troubles with function ordering
|
||||
inline char* end( char* s )
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
@ -103,13 +105,75 @@ namespace range
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
}
|
||||
|
||||
} // namespace 'range'
|
||||
#else
|
||||
inline char* end( char*& s )
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
}
|
||||
|
||||
using range::end;
|
||||
inline wchar_t* end( wchar_t*& s )
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
}
|
||||
|
||||
inline const char* end( const char*& s )
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
}
|
||||
|
||||
inline const wchar_t* end( const wchar_t*& s )
|
||||
{
|
||||
return range_detail::str_end( s );
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace 'range_detail'
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type end( T& r )
|
||||
{
|
||||
return range_detail::end( r );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type end( const T& r )
|
||||
{
|
||||
return range_detail::end( r );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 3003 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// BCB and CW are not able to overload pointer when class overloads are also available.
|
||||
template<>
|
||||
inline range_const_iterator<const char*>::type end<const char*>( const char*& r )
|
||||
{
|
||||
return range_detail::str_end( r );
|
||||
}
|
||||
|
||||
template<>
|
||||
inline range_const_iterator<const wchar_t*>::type end<const wchar_t*>( const wchar_t*& r )
|
||||
{
|
||||
return range_detail::str_end( r );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace 'boost'
|
||||
|
||||
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_iterator<T>::type
|
||||
const_end( const T& r )
|
||||
{
|
||||
return end( r );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct iterator_of
|
||||
struct range_iterator
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::iterator type;
|
||||
};
|
||||
@ -42,13 +42,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_of< std::pair<Iterator,Iterator> >
|
||||
struct range_iterator< std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
struct iterator_of< const std::pair<Iterator,Iterator> >
|
||||
struct range_iterator< const std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef Iterator type;
|
||||
};
|
||||
@ -58,13 +58,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct iterator_of< T[sz] >
|
||||
struct range_iterator< T[sz] >
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct iterator_of< const T[sz] >
|
||||
struct range_iterator< const T[sz] >
|
||||
{
|
||||
typedef const T* type;
|
||||
};
|
||||
@ -74,25 +74,25 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct iterator_of< char* >
|
||||
struct range_iterator< char* >
|
||||
{
|
||||
typedef char* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct iterator_of< wchar_t* >
|
||||
struct range_iterator< wchar_t* >
|
||||
{
|
||||
typedef wchar_t* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct iterator_of< const char* >
|
||||
struct range_iterator< const char* >
|
||||
{
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct iterator_of< const wchar_t* >
|
||||
struct range_iterator< const wchar_t* >
|
||||
{
|
||||
typedef const wchar_t* type;
|
||||
};
|
||||
|
@ -11,11 +11,10 @@
|
||||
#ifndef BOOST_RANGE_ITERATOR_RANGE_HPP
|
||||
#define BOOST_RANGE_ITERATOR_RANGE_HPP
|
||||
|
||||
#include <boost/range/config.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/functions.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <ostream>
|
||||
@ -30,6 +29,32 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace range_detail
|
||||
{
|
||||
template< class Left, class Right >
|
||||
inline bool equal( const Left& l, const Right& r )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_size<Left>::type sz_type;
|
||||
sz_type l_size = boost::size( l ),
|
||||
r_size = boost::size( r );
|
||||
|
||||
if( l_size != r_size )
|
||||
return false;
|
||||
|
||||
return std::equal( boost::begin(l), boost::end(l),
|
||||
boost::begin(r) );
|
||||
}
|
||||
|
||||
template< class Left, class Right >
|
||||
inline bool less_than( const Left& l, const Right& r )
|
||||
{
|
||||
return std::lexicographical_compare( boost::begin(l),
|
||||
boost::end(l),
|
||||
boost::begin(r),
|
||||
boost::end(r) );
|
||||
}
|
||||
}
|
||||
|
||||
// iterator range template class -----------------------------------------//
|
||||
|
||||
//! iterator_range class
|
||||
@ -55,11 +80,14 @@ namespace boost {
|
||||
public:
|
||||
//! this type
|
||||
typedef iterator_range<IteratorT> type;
|
||||
//BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type);
|
||||
|
||||
//! Encapsulated value type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_value<IteratorT>::type value_type;
|
||||
|
||||
//! Difference type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_difference<IteratorT>::type difference_type;
|
||||
//! Size type
|
||||
typedef std::size_t size_type; // note: must be unsigned
|
||||
@ -73,69 +101,55 @@ namespace boost {
|
||||
//! iterator type
|
||||
typedef IteratorT iterator;
|
||||
|
||||
//! Default constructor
|
||||
iterator_range() {}
|
||||
iterator_range() : m_Begin( iterator() ), m_End( iterator() ),
|
||||
singular( true )
|
||||
{ }
|
||||
|
||||
//! Constructor from a pair of iterators
|
||||
iterator_range( iterator Begin, iterator End ) :
|
||||
m_Begin(Begin), m_End(End) {}
|
||||
template< class Iterator >
|
||||
iterator_range( Iterator Begin, Iterator End ) :
|
||||
m_Begin(Begin), m_End(End), singular(false) {}
|
||||
|
||||
//! Constructor from a Range
|
||||
template< class Range >
|
||||
iterator_range( const Range& r ) :
|
||||
m_Begin( boost::begin( r ) ), m_End( boost::end( r ) ) {}
|
||||
m_Begin( adl_begin( r ) ), m_End( adl_end( r ) ),
|
||||
singular(false) {}
|
||||
|
||||
//! Constructor from a Range
|
||||
template< class Range >
|
||||
iterator_range( Range& r ) :
|
||||
m_Begin( boost::begin( r ) ), m_End( boost::end( r ) ) {}
|
||||
|
||||
//! Copy constructor
|
||||
iterator_range( const iterator_range& Other ) :
|
||||
m_Begin(Other.begin()), m_End(Other.end()) {}
|
||||
|
||||
//! Templated copy constructor
|
||||
/*!
|
||||
This constructor is provided to allow conversion between
|
||||
const and mutable iterator instances of this class template
|
||||
*/
|
||||
template< typename OtherItT >
|
||||
iterator_range( const iterator_range<OtherItT>& Other ) :
|
||||
m_Begin(Other.begin()), m_End(Other.end()) {}
|
||||
|
||||
//! Assignment operator
|
||||
iterator_range& operator=( const iterator_range& Other )
|
||||
{
|
||||
m_Begin=Other.begin(); m_End=Other.end();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Assignment operator ( templated version )
|
||||
template< typename OtherItT >
|
||||
iterator_range& operator=( const iterator_range<OtherItT>& Other )
|
||||
{
|
||||
m_Begin=Other.begin(); m_End=Other.end();
|
||||
return *this;
|
||||
}
|
||||
m_Begin( adl_begin( r ) ), m_End( adl_end( r ) ),
|
||||
singular(false) {}
|
||||
|
||||
//! Comparison operator ( equal )
|
||||
/*!
|
||||
Compare operands for equality
|
||||
*/
|
||||
template< typename OtherItT >
|
||||
bool operator==( const iterator_range<OtherItT>& Other ) const
|
||||
template< class Iterator >
|
||||
iterator_range& operator=( const iterator_range<Iterator>& r )
|
||||
{
|
||||
return ! (*this != Other);
|
||||
m_Begin = r.begin();
|
||||
m_End = r.end();
|
||||
//
|
||||
// remark: this need not necessarily be true, but it does no harm
|
||||
//
|
||||
singular = r.empty();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class ForwardRange >
|
||||
iterator_range& operator=( ForwardRange& r )
|
||||
{
|
||||
m_Begin = adl_begin( r );
|
||||
m_End = adl_end( r );
|
||||
singular = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Comparison operator ( not-equal )
|
||||
/*!
|
||||
Compare operands for non-equality
|
||||
*/
|
||||
template< typename OtherItT >
|
||||
bool operator!=( const iterator_range<OtherItT>& Other ) const
|
||||
template< class ForwardRange >
|
||||
iterator_range& operator=( const ForwardRange& r )
|
||||
{
|
||||
return m_Begin!=Other.begin() || m_End!=Other.end();
|
||||
m_Begin = adl_begin( r );
|
||||
m_End = adl_end( r );
|
||||
singular = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! begin access
|
||||
@ -162,24 +176,20 @@ namespace boost {
|
||||
*/
|
||||
size_type size() const
|
||||
{
|
||||
if( singular )
|
||||
return 0;
|
||||
|
||||
return std::distance( m_Begin, m_End );
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
if( singular )
|
||||
return true;
|
||||
|
||||
return m_Begin == m_End;
|
||||
}
|
||||
|
||||
//! Swap
|
||||
/*!
|
||||
Swap two ranges
|
||||
*/
|
||||
void swap( iterator_range& Other )
|
||||
{
|
||||
std::swap( m_Begin, Other.m_Begin );
|
||||
std::swap( m_End, Other.m_End );
|
||||
}
|
||||
|
||||
//! Safe bool conversion
|
||||
/*!
|
||||
Check whenever the range is empty.
|
||||
@ -197,37 +207,163 @@ namespace boost {
|
||||
{
|
||||
return empty() ? 0: &iterator_range::end;
|
||||
}
|
||||
|
||||
/*
|
||||
inline operator t_type() const
|
||||
{
|
||||
return make_tuple( m_Begin, m_End );
|
||||
}*/
|
||||
|
||||
bool equal( const iterator_range& r ) const
|
||||
{
|
||||
return singular == r.singular && m_Begin == r.m_Begin && m_End == r.m_End;
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
bool operator==( const iterator_range& r ) const
|
||||
{
|
||||
return range_detail::equal( *this, r );
|
||||
}
|
||||
|
||||
bool operator!=( const iterator_range& r ) const
|
||||
{
|
||||
return !operator==(r);
|
||||
}
|
||||
|
||||
bool operator<( const iterator_range& r ) const
|
||||
{
|
||||
return range_detail::less_than( *this, r );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
template< class ForwardRange >
|
||||
iterator adl_begin( ForwardRange& r )
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
return boost::begin( r );
|
||||
#else
|
||||
using boost::begin;
|
||||
return iterator( begin( r ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< class ForwardRange >
|
||||
iterator adl_end( ForwardRange& r )
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
return boost::end( r );
|
||||
#else
|
||||
using boost::end;
|
||||
return iterator( end( r ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
// begin and end iterators
|
||||
IteratorT m_Begin;
|
||||
IteratorT m_End;
|
||||
bool singular;
|
||||
};
|
||||
|
||||
// iterator range free-standing operators ---------------------------//
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
#else
|
||||
template< class Iterator >
|
||||
inline bool empty( const iterator_range<Iterator>& r )
|
||||
{
|
||||
//
|
||||
// this will preserve the well-defined empty() even
|
||||
// though 'r' is singular.
|
||||
//
|
||||
return r.empty();
|
||||
}
|
||||
#endif
|
||||
|
||||
//! iterator_range output operator
|
||||
/*!
|
||||
Output the range to an ostream. Elements are outputed
|
||||
in a sequence without separators.
|
||||
*/
|
||||
template< typename IteratorT, typename Elem, typename Traits >
|
||||
std::basic_ostream<Elem,Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& Os,
|
||||
const iterator_range<IteratorT>& r )
|
||||
inline std::basic_ostream<Elem,Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& Os,
|
||||
const iterator_range<IteratorT>& r )
|
||||
{
|
||||
std::copy( begin(r), end(r), std::ostream_iterator<Elem>(Os));
|
||||
|
||||
return Os;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// comparison operators
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator==( const ForwardRange& l,
|
||||
const iterator_range<IteratorT>& r )
|
||||
{
|
||||
return range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator!=( const ForwardRange& l,
|
||||
const iterator_range<IteratorT>& r )
|
||||
{
|
||||
return !range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator<( const ForwardRange& l,
|
||||
const iterator_range<IteratorT>& r )
|
||||
{
|
||||
return range_detail::less_than( l, r );
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
#else
|
||||
template< class Iterator1T, class Iterator2T >
|
||||
inline bool operator==( const iterator_range<Iterator1T>& l,
|
||||
const iterator_range<Iterator2T>& r )
|
||||
{
|
||||
return range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator==( const iterator_range<IteratorT>& l,
|
||||
const ForwardRange& r )
|
||||
{
|
||||
return range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
|
||||
template< class Iterator1T, class Iterator2T >
|
||||
inline bool operator!=( const iterator_range<Iterator1T>& l,
|
||||
const iterator_range<Iterator2T>& r )
|
||||
{
|
||||
return !range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator!=( const iterator_range<IteratorT>& l,
|
||||
const ForwardRange& r )
|
||||
{
|
||||
return !range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
|
||||
template< class Iterator1T, class Iterator2T >
|
||||
inline bool operator<( const iterator_range<Iterator1T>& l,
|
||||
const iterator_range<Iterator2T>& r )
|
||||
{
|
||||
return range_detail::less_than( l, r );
|
||||
}
|
||||
|
||||
template< class IteratorT, class ForwardRange >
|
||||
inline bool operator<( const iterator_range<IteratorT>& l,
|
||||
const ForwardRange& r )
|
||||
{
|
||||
return range_detail::less_than( l, r );
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
// iterator range utilities -----------------------------------------//
|
||||
|
||||
//! iterator_range construct helper
|
||||
@ -244,28 +380,42 @@ namespace boost {
|
||||
{
|
||||
return iterator_range<IteratorT>( Begin, End );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
template< typename Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
make_iterator_range( Range& r )
|
||||
{
|
||||
return iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
( begin( r ), end( r ) );
|
||||
}
|
||||
|
||||
#else
|
||||
//! iterator_range construct helper
|
||||
/*!
|
||||
Construct an \c iterator_range from a \c Range containing the begin
|
||||
and end iterators.
|
||||
*/
|
||||
template< typename Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME iterator_of<Range>::type >
|
||||
make_iterator_range( Range& r )
|
||||
template< class ForwardRange >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
|
||||
make_iterator_range( ForwardRange& r )
|
||||
{
|
||||
return iterator_range< BOOST_DEDUCED_TYPENAME iterator_of<Range>::type >
|
||||
return iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<ForwardRange>::type >
|
||||
( r );
|
||||
}
|
||||
|
||||
template< typename Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME const_iterator_of<Range>::type >
|
||||
make_iterator_range( const Range& r )
|
||||
template< class ForwardRange >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<ForwardRange>::type >
|
||||
make_iterator_range( const ForwardRange& r )
|
||||
{
|
||||
return iterator_range< BOOST_DEDUCED_TYPENAME const_iterator_of<Range>::type >
|
||||
return iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<ForwardRange>::type >
|
||||
( r );
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
//! copy a range into a sequence
|
||||
/*!
|
||||
Construct a new sequence of the specified type from the elements
|
||||
|
@ -8,8 +8,8 @@
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
|
||||
#ifndef BOOST_RANGE_TYPES_HPP
|
||||
#define BOOST_RANGE_TYPES_HPP
|
||||
#ifndef BOOST_RANGE_METAFUNCTIONS_HPP
|
||||
#define BOOST_RANGE_METAFUNCTIONS_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
# pragma once
|
@ -16,26 +16,51 @@
|
||||
#endif
|
||||
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/reverse_result_iterator.hpp>
|
||||
#include <boost/range/reverse_iterator.hpp>
|
||||
#include <boost/range/const_reverse_iterator.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME reverse_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
|
||||
rbegin( C& c )
|
||||
{
|
||||
return BOOST_DEDUCED_TYPENAME reverse_iterator_of<C>::type( end( c ) );
|
||||
return BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type( end( c ) );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
|
||||
rbegin( C& c )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
|
||||
iter_type;
|
||||
return iter_type( end( c ) );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME const_reverse_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
|
||||
rbegin( const C& c )
|
||||
{
|
||||
return BOOST_DEDUCED_TYPENAME const_reverse_iterator_of<C>::type( end( c ) );
|
||||
typedef BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
|
||||
iter_type;
|
||||
return iter_type( end( c ) );
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<T>::type
|
||||
const_rbegin( const T& r )
|
||||
{
|
||||
return rbegin( r );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
||||
#endif
|
||||
|
@ -16,24 +16,49 @@
|
||||
#endif
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/reverse_result_iterator.hpp>
|
||||
#include <boost/range/reverse_iterator.hpp>
|
||||
#include <boost/range/const_reverse_iterator.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME reverse_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type
|
||||
rend( C& c )
|
||||
{
|
||||
return BOOST_DEDUCED_TYPENAME reverse_iterator_of<C>::type( begin( c ) );
|
||||
return BOOST_DEDUCED_TYPENAME range_reverse_result_iterator<C>::type( begin( c ) );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
|
||||
rend( C& c )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME range_reverse_iterator<C>::type
|
||||
iter_type;
|
||||
return iter_type( begin( c ) );
|
||||
}
|
||||
|
||||
template< class C >
|
||||
inline BOOST_DEDUCED_TYPENAME const_reverse_iterator_of<C>::type
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
|
||||
rend( const C& c )
|
||||
{
|
||||
return BOOST_DEDUCED_TYPENAME const_reverse_iterator_of<C>::type( begin( c ) );
|
||||
typedef BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<C>::type
|
||||
iter_type;
|
||||
return iter_type( begin( c ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_const_reverse_iterator<T>::type
|
||||
const_rend( const T& r )
|
||||
{
|
||||
return rend( r );
|
||||
}
|
||||
|
||||
} // namespace 'boost'
|
||||
|
@ -28,12 +28,12 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct result_iterator_of
|
||||
struct range_result_iterator
|
||||
{
|
||||
typedef BOOST_CT_DEDUCED_TYPENAME
|
||||
typedef BOOST_RANGE_DEDUCED_TYPENAME
|
||||
mpl::if_< BOOST_DEDUCED_TYPENAME is_const<C>::type,
|
||||
BOOST_DEDUCED_TYPENAME const_iterator_of<C>::type,
|
||||
BOOST_DEDUCED_TYPENAME iterator_of<C>::type >::type type;
|
||||
BOOST_DEDUCED_TYPENAME range_const_iterator<C>::type,
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<C>::type >::type type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
@ -27,10 +27,10 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct reverse_iterator_of
|
||||
struct range_reverse_iterator
|
||||
{
|
||||
typedef reverse_iterator<
|
||||
BOOST_DEDUCED_TYPENAME iterator_of<C>::type > type;
|
||||
BOOST_DEDUCED_TYPENAME range_iterator<C>::type > type;
|
||||
};
|
||||
|
||||
|
||||
|
@ -26,10 +26,10 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct reverse_result_iterator_of
|
||||
struct range_reverse_result_iterator
|
||||
{
|
||||
typedef reverse_iterator<
|
||||
BOOST_DEDUCED_TYPENAME result_iterator_of<C>::type > type;
|
||||
BOOST_DEDUCED_TYPENAME range_result_iterator<C>::type > type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
@ -22,20 +22,22 @@
|
||||
#else
|
||||
|
||||
#include <boost/range/detail/implementation_help.hpp>
|
||||
#include <boost/range/size_type.hpp>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace range
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default
|
||||
// primary template
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
inline BOOST_CT_DEDUCED_TYPENAME C::size_type
|
||||
inline BOOST_DEDUCED_TYPENAME C::size_type
|
||||
size( const C& c )
|
||||
{
|
||||
return c.size();
|
||||
@ -58,32 +60,54 @@ namespace range
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t size( const T (&array)[sz] )
|
||||
{
|
||||
return range_detail::array_size( array );
|
||||
return range_detail::array_size<T,sz>( array );
|
||||
}
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
inline std::size_t size( T (&array)[sz] )
|
||||
{
|
||||
return range_detail::array_size( array );
|
||||
return boost::range_detail::array_size<T,sz>( array );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::size_t size( const char* s )
|
||||
inline std::size_t size( const char* const& s )
|
||||
{
|
||||
return range_detail::str_size( s );
|
||||
return boost::range_detail::str_size( s );
|
||||
}
|
||||
|
||||
inline std::size_t size( const wchar_t* s )
|
||||
inline std::size_t size( const wchar_t* const& s )
|
||||
{
|
||||
return range_detail::str_size( s );
|
||||
return boost::range_detail::str_size( s );
|
||||
}
|
||||
|
||||
} // namespace 'range'
|
||||
} // namespace 'range_detail'
|
||||
|
||||
template< class T >
|
||||
inline BOOST_DEDUCED_TYPENAME range_size<T>::type size( const T& r )
|
||||
{
|
||||
return range_detail::size( r );
|
||||
}
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 3003 ) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
// BCB and CW are not able to overload pointer when class overloads are also available.
|
||||
inline range_size<const char*>::type size( const char* r ) {
|
||||
return range_detail::str_size( r );
|
||||
}
|
||||
inline range_size<char*>::type size( char* r ) {
|
||||
return range_detail::str_size( r );
|
||||
}
|
||||
inline range_size<const wchar_t*>::type size( const wchar_t* r ) {
|
||||
return range_detail::str_size( r );
|
||||
}
|
||||
inline range_size<wchar_t*>::type size( wchar_t* r ) {
|
||||
return range_detail::str_size( r );
|
||||
}
|
||||
#endif
|
||||
|
||||
using range::size;
|
||||
|
||||
} // namespace 'boost'
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct size_type_of
|
||||
struct range_size
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::size_type type;
|
||||
};
|
||||
@ -41,13 +41,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Iterator >
|
||||
struct size_type_of< std::pair<Iterator,Iterator> >
|
||||
struct range_size< std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
||||
template< typename Iterator >
|
||||
struct size_type_of< const std::pair<Iterator,Iterator> >
|
||||
struct range_size< const std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
@ -57,13 +57,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct size_type_of< T[sz] >
|
||||
struct range_size< T[sz] >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct size_type_of< const T[sz] >
|
||||
struct range_size< const T[sz] >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
@ -73,25 +73,25 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct size_type_of< char* >
|
||||
struct range_size< char* >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct size_type_of< wchar_t* >
|
||||
struct range_size< wchar_t* >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct size_type_of< const char* >
|
||||
struct range_size< const char* >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct size_type_of< const wchar_t* >
|
||||
struct range_size< const wchar_t* >
|
||||
{
|
||||
typedef std::size_t type;
|
||||
};
|
||||
|
@ -13,36 +13,49 @@
|
||||
|
||||
#include <boost/range/config.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
#include <boost/range/reverse_result_iterator.hpp>
|
||||
#include <boost/range/size_type.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
//#include <boost/range/rbegin.hpp>
|
||||
//#include <boost/range/rend.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template< class Range >
|
||||
class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME result_iterator_of<Range>::type >
|
||||
template< class ForwardRange >
|
||||
class sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<ForwardRange>::type >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME result_iterator_of<Range>::type iterator_t;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_result_iterator<ForwardRange>::type iterator_t;
|
||||
typedef iterator_range< iterator_t > base;
|
||||
|
||||
public:
|
||||
using base::iterator;
|
||||
using base::const_iterator;
|
||||
using base::value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME difference_type_of<Range>::type difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME size_type_of<Range>::type size_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_value<ForwardRange>::type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_result_iterator<ForwardRange>::type iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_const_iterator<ForwardRange>::type const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_difference<ForwardRange>::type difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME range_size<ForwardRange>::type size_type;
|
||||
|
||||
public:
|
||||
template< class Range2 >
|
||||
sub_range( Range2& r ) : base( r )
|
||||
sub_range() : base()
|
||||
{ }
|
||||
|
||||
template< class ForwardRange2 >
|
||||
sub_range( ForwardRange2& r ) :
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
|
||||
base( boost::begin( r ), boost::end( r ) )
|
||||
#else
|
||||
base( r )
|
||||
#endif
|
||||
{ }
|
||||
|
||||
template< class Range2 >
|
||||
sub_range( const Range2& r ) : base( r )
|
||||
template< class ForwardRange2 >
|
||||
sub_range( const ForwardRange2& r ) :
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 800 )
|
||||
base( boost::begin( r ), boost::end( r ) )
|
||||
#else
|
||||
base( r )
|
||||
#endif
|
||||
{ }
|
||||
|
||||
template< class Iter >
|
||||
@ -50,77 +63,52 @@ namespace boost
|
||||
base( first, last )
|
||||
{ }
|
||||
|
||||
template< class Range2 >
|
||||
sub_range& operator=( Range2& r )
|
||||
template< class ForwardRange2 >
|
||||
sub_range& operator=( ForwardRange2& r )
|
||||
{
|
||||
base::operator=( r );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class Range2 >
|
||||
sub_range& operator=( const Range2& r )
|
||||
template< class ForwardRange2 >
|
||||
sub_range& operator=( const ForwardRange2& r )
|
||||
{
|
||||
base::operator=( r );
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
//
|
||||
// performance discontinuity problem!!
|
||||
//
|
||||
return base::size();
|
||||
}
|
||||
public:
|
||||
|
||||
iterator begin() { return base::begin(); }
|
||||
const_iterator begin() const { return base::begin(); }
|
||||
iterator end() { return base::end(); }
|
||||
const_iterator end() const { return base::end(); }
|
||||
size_type size() const { return base::size(); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
template< class Range >
|
||||
class reverse_sub_range : public iterator_range< BOOST_DEDUCED_TYPENAME reverse_result_iterator_of<Range>::type >
|
||||
|
||||
template< class ForwardRange, class ForwardRange2 >
|
||||
inline bool operator==( const sub_range<ForwardRange>& l,
|
||||
const sub_range<ForwardRange2>& r )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME reverse_result_iterator_of<Range>::type
|
||||
iterator_t;
|
||||
typedef iterator_range<iterator_t> base;
|
||||
|
||||
public:
|
||||
using base::iterator;
|
||||
using base::const_iterator;
|
||||
using base::value_type;
|
||||
using base::difference_type;
|
||||
using base::size_type;
|
||||
|
||||
public:
|
||||
template< class Range2 >
|
||||
reverse_sub_range( Range2& r ) : base( rbegin( r ), rend( r ) )
|
||||
{ }
|
||||
|
||||
template< class Range2 >
|
||||
reverse_sub_range( const Range2& r ) : base( rbegin( r ), rend( r ) )
|
||||
{ }
|
||||
return range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class Iter >
|
||||
reverse_sub_range( Iter first, Iter last ) :
|
||||
base( iterator_t( last ), iterator_t( first ) )
|
||||
{ }
|
||||
template< class ForwardRange, class ForwardRange2 >
|
||||
inline bool operator!=( const sub_range<ForwardRange>& l,
|
||||
const sub_range<ForwardRange2>& r )
|
||||
{
|
||||
return !range_detail::equal( l, r );
|
||||
}
|
||||
|
||||
template< class ForwardRange, class ForwardRange2 >
|
||||
inline bool operator<( const sub_range<ForwardRange>& l,
|
||||
const sub_range<ForwardRange2>& r )
|
||||
{
|
||||
return range_detail::less_than( l, r );
|
||||
}
|
||||
|
||||
template< class Range2 >
|
||||
sub_range& operator=( Range2& r )
|
||||
{
|
||||
base::operator=( r );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class Range2 >
|
||||
sub_range& operator=( const Range2& r )
|
||||
{
|
||||
base::operator=( r );
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
*/
|
||||
|
||||
} // namespace 'boost'
|
||||
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename C >
|
||||
struct value_type_of
|
||||
struct range_value
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::value_type type;
|
||||
};
|
||||
@ -43,7 +43,7 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename Iterator >
|
||||
struct value_type_of< std::pair<Iterator,Iterator> >
|
||||
struct range_value< std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_value<Iterator>::type type;
|
||||
@ -51,7 +51,7 @@ namespace boost
|
||||
|
||||
|
||||
template< typename Iterator >
|
||||
struct value_type_of< const std::pair<Iterator,Iterator> >
|
||||
struct range_value< const std::pair<Iterator,Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
iterator_value<Iterator>::type type;
|
||||
@ -62,13 +62,13 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct value_type_of< T[sz] >
|
||||
struct range_value< T[sz] >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template< typename T, std::size_t sz >
|
||||
struct value_type_of< const T[sz] >
|
||||
struct range_value< const T[sz] >
|
||||
{
|
||||
typedef const T type;
|
||||
};
|
||||
@ -78,25 +78,25 @@ namespace boost
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
struct value_type_of< char* >
|
||||
struct range_value< char* >
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_type_of< wchar_t* >
|
||||
struct range_value< wchar_t* >
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_type_of< const char* >
|
||||
struct range_value< const char* >
|
||||
{
|
||||
typedef const char type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct value_type_of< const wchar_t* >
|
||||
struct range_value< const wchar_t* >
|
||||
{
|
||||
typedef const wchar_t type;
|
||||
};
|
||||
|
84
index.html
Executable file
84
index.html
Executable file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Boost.Range Documentation </title>
|
||||
<link rel="stylesheet" href="doc/style.css" type="text/css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table border="0" >
|
||||
<tr>
|
||||
<td ><img src="../../boost.png" border="0" ></td>
|
||||
<td >
|
||||
<h1 align="center">Range Library</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Copyright <20> 2003-2004 Thorsten Ottosen
|
||||
</p>
|
||||
<p>
|
||||
Use, modification and distribution is subject to the Boost Software License, Version 1.0
|
||||
(see <a href=http://www.boost.org/LICENSE_1_0.txt>
|
||||
http://www.boost.org/LICENSE_1_0.txt</a>).
|
||||
</p>
|
||||
|
||||
<h1>Overview</h1>
|
||||
<p>
|
||||
Boost.Range is a collection of concepts and utilities that are particularly
|
||||
useful for specifying and implementing generic algorithms. The documentation
|
||||
consists of the following sections:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> <a href=doc/intro.html>Introduction </a></code>
|
||||
|
||||
<li><a href=doc/range.html>Range concepts:</a>
|
||||
<ul>
|
||||
<li> <a href="doc/range.html#single_pass_range">SinglePassRange</a>
|
||||
<li> <a href="doc/range.html#range">ForwardRange</a>
|
||||
<li> <a href="doc/range.html#reversible_range">BidirectionalRange</a>
|
||||
<li> <a href="doc/range.html#random_access_range">RandomAccessRange</a> </ul>
|
||||
|
||||
<li> <a href=doc/boost_range.html>Implementation</a> of Range concepts
|
||||
<li> <a href=doc/utility_class.html> Utilities:</a>
|
||||
<ul>
|
||||
<li> Class <a href="doc/utility_class.html#iter_range"><code>iterator_range</code></a>
|
||||
<li> Class <a href="doc/utility_class.html#sub_range"><code>sub_range</code></a> </ul>
|
||||
|
||||
<li> <a href=doc/style.html>Terminology and style guidelines </a>
|
||||
<li><a href="doc/headers.html">Headers</a> </li>
|
||||
<li><a href="doc/examples.html">Examples</a>
|
||||
<li><a href="doc/portability.html">Portability</a>
|
||||
<li><a href="doc/faq.html">FAQ</a>
|
||||
<li><a href="doc/history_ack.html">History and acknowledgment</a>
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
(C) Copyright Thorsten Ottosen 2003-2004
|
||||
</p>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
103
test/Jamfile
Executable file
103
test/Jamfile
Executable file
@ -0,0 +1,103 @@
|
||||
# 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/
|
||||
#
|
||||
|
||||
subproject libs/range/test ;
|
||||
|
||||
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
|
||||
include testing.jam ;
|
||||
DEPENDS all : test ;
|
||||
|
||||
{
|
||||
test-suite range
|
||||
: [ run
|
||||
array.cpp
|
||||
: :
|
||||
:
|
||||
: array_test
|
||||
]
|
||||
[ run
|
||||
iterator_pair.cpp
|
||||
: :
|
||||
:
|
||||
: iterator_pair_test
|
||||
]
|
||||
[ run
|
||||
std_container.cpp
|
||||
: :
|
||||
:
|
||||
: std_container_test
|
||||
]
|
||||
[ run
|
||||
string.cpp
|
||||
: :
|
||||
:
|
||||
: string_test
|
||||
]
|
||||
[ run
|
||||
iterator_range.cpp
|
||||
: :
|
||||
:
|
||||
: iterator_range
|
||||
]
|
||||
[ run
|
||||
sub_range.cpp
|
||||
: :
|
||||
:
|
||||
: sub_range
|
||||
]
|
||||
|
||||
[ run
|
||||
partial_workaround.cpp
|
||||
: :
|
||||
:
|
||||
: workaround_test
|
||||
]
|
||||
[ run
|
||||
algorithm_example.cpp
|
||||
: :
|
||||
:
|
||||
: example_test
|
||||
]
|
||||
|
||||
[ run
|
||||
reversible_range.cpp
|
||||
: :
|
||||
:
|
||||
: reversible_range_test
|
||||
]
|
||||
[ run
|
||||
const_ranges.cpp
|
||||
: :
|
||||
:
|
||||
: const_ranges
|
||||
]
|
||||
# [ run
|
||||
# compat3.cpp
|
||||
# : :
|
||||
# :
|
||||
# : compat3_test
|
||||
# ]
|
||||
#
|
||||
# [ run
|
||||
# adl_conformance.cpp
|
||||
# : :
|
||||
# :
|
||||
# : adl_conformance
|
||||
# ]
|
||||
# [ run
|
||||
# adl_conformance_no_using.cpp
|
||||
# : :
|
||||
# :
|
||||
# : adl_conformance_no_using_declaration
|
||||
# ]
|
||||
|
||||
;
|
||||
|
||||
}
|
111
test/TODO
Normal file
111
test/TODO
Normal file
@ -0,0 +1,111 @@
|
||||
17. post-review question: should Range mean lowest common denominator? or
|
||||
perhaps Forward Range? problem with not being explicit.
|
||||
|
||||
18. maybe iterator_range operator==() should be defined when rhs or lhs
|
||||
take a forward range argument; this comparison function should
|
||||
then call std::lexigraphical_compare(....). Example:
|
||||
|
||||
sub_range<string> sub = ...;
|
||||
if( sub == "foo" )
|
||||
|
||||
/*
|
||||
namespace range_detail
|
||||
{
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
make_sub_range_impl( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
|
||||
{
|
||||
BOOST_ASSERT( advance_begin >= 0 );
|
||||
BOOST_ASSERT( advance_end >= 0 );
|
||||
|
||||
BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type
|
||||
new_begin = begin( r ),
|
||||
new_end = end( r );
|
||||
std::advance( new_begin, advance_begin );
|
||||
std::advance( new_end, -advance_end );
|
||||
return make_iterator_range( new_begin, new_end );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
make_super_range_impl( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end )
|
||||
{
|
||||
BOOST_ASSERT( advance_begin >= 0 );
|
||||
BOOST_ASSERT( advance_end >= 0 );
|
||||
|
||||
BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type
|
||||
new_begin = begin( r ),
|
||||
new_end = end( r );
|
||||
std::advance( new_begin, -advance_begin );
|
||||
std::advance( new_end, advance_end );
|
||||
return make_iterator_range( new_begin, new_end );
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
/*
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
make_sub_range( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_sub_range_impl( r, advance_begin, advance_end );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_result_iterator<Range>::type >
|
||||
make_super_range( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_super_range_impl( r, advance_begin, advance_end );
|
||||
}*/
|
||||
/*
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
|
||||
make_sub_range( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_sub_range_impl( r, advance_begin, advance_end );
|
||||
}
|
||||
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<Range>::type >
|
||||
make_sub_range( const Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_sub_range_impl( r, advance_begin, advance_end );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<Range>::type >
|
||||
make_super_range( Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_super_range_impl( r, advance_begin, advance_end );
|
||||
}
|
||||
|
||||
|
||||
template< class Range >
|
||||
inline iterator_range< BOOST_DEDUCED_TYPENAME range_const_iterator<Range>::type >
|
||||
make_super_range( const Range& r,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_begin,
|
||||
BOOST_DEDUCED_TYPENAME range_difference<Range>::type advance_end = 0 )
|
||||
{
|
||||
return range_detail::make_super_range_impl( r, advance_begin, advance_end );
|
||||
}*/
|
||||
|
185
test/adl_conformance.cpp
Executable file
185
test/adl_conformance.cpp
Executable file
@ -0,0 +1,185 @@
|
||||
// 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/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
enum adl_types
|
||||
{
|
||||
unused,
|
||||
boost_namespace,
|
||||
templated_namespace,
|
||||
non_templated_namespace,
|
||||
global_namespace
|
||||
};
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
template< class Range >
|
||||
inline typename Range::iterator begin( Range& r )
|
||||
{
|
||||
return boost_namespace;
|
||||
}
|
||||
|
||||
template< class Range >
|
||||
inline typename Range::iterator begin( const Range& r )
|
||||
{
|
||||
return boost_namespace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template< class Range >
|
||||
inline typename Range::iterator begin( Range& r )
|
||||
{
|
||||
using range_detail::begin; // create ADL hook
|
||||
return begin( r );
|
||||
}
|
||||
|
||||
template< class Range >
|
||||
inline typename Range::iterator begin( const Range& r )
|
||||
{
|
||||
using range_detail::begin; // create ADL hook
|
||||
return begin( r );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace find_templated
|
||||
{
|
||||
template< class T >
|
||||
struct range
|
||||
{
|
||||
typedef adl_types iterator;
|
||||
|
||||
range() { /* allow const objects */ }
|
||||
iterator begin() { return unused; }
|
||||
iterator begin() const { return unused; }
|
||||
iterator end() { return unused; }
|
||||
iterator end() const { return unused; }
|
||||
};
|
||||
|
||||
//
|
||||
// A fully generic version here will create
|
||||
// ambiguity.
|
||||
//
|
||||
template< class T >
|
||||
inline typename range<T>::iterator begin( range<T>& r )
|
||||
{
|
||||
return templated_namespace;
|
||||
}
|
||||
|
||||
template< class T >
|
||||
inline typename range<T>::iterator begin( const range<T>& r )
|
||||
{
|
||||
return templated_namespace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace find_non_templated
|
||||
{
|
||||
struct range
|
||||
{
|
||||
typedef adl_types iterator;
|
||||
|
||||
range() { /* allow const objects */ }
|
||||
iterator begin() { return unused; }
|
||||
iterator begin() const { return unused; }
|
||||
iterator end() { return unused; }
|
||||
iterator end() const { return unused; }
|
||||
};
|
||||
|
||||
inline range::iterator begin( range& r )
|
||||
{
|
||||
return non_templated_namespace;
|
||||
}
|
||||
|
||||
|
||||
inline range::iterator begin( const range& r )
|
||||
{
|
||||
return non_templated_namespace;
|
||||
}
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
typedef adl_types iterator;
|
||||
|
||||
range() { /* allow const objects */ }
|
||||
iterator begin() { return unused; }
|
||||
iterator begin() const { return unused; }
|
||||
iterator end() { return unused; }
|
||||
iterator end() const { return unused; }
|
||||
};
|
||||
|
||||
inline range::iterator begin( range& r )
|
||||
{
|
||||
return global_namespace;
|
||||
}
|
||||
|
||||
inline range::iterator begin( const range& r )
|
||||
{
|
||||
return global_namespace;
|
||||
}
|
||||
|
||||
void check_adl_conformance()
|
||||
{
|
||||
find_templated::range<int> r;
|
||||
const find_templated::range<int> r2;
|
||||
find_non_templated::range r3;
|
||||
const find_non_templated::range r4;
|
||||
range r5;
|
||||
const range r6;
|
||||
|
||||
//
|
||||
// Notice how ADL kicks in even when we have qualified
|
||||
// notation!
|
||||
//
|
||||
|
||||
|
||||
BOOST_CHECK( boost::begin( r ) != boost_namespace );
|
||||
BOOST_CHECK( boost::begin( r2 ) != boost_namespace );
|
||||
BOOST_CHECK( boost::begin( r3 ) != boost_namespace );
|
||||
BOOST_CHECK( boost::begin( r4 ) != boost_namespace );
|
||||
BOOST_CHECK( boost::begin( r5 ) != boost_namespace );
|
||||
BOOST_CHECK( boost::begin( r6 ) != boost_namespace );
|
||||
|
||||
BOOST_CHECK_EQUAL( boost::begin( r ), templated_namespace ) ;
|
||||
BOOST_CHECK_EQUAL( boost::begin( r2 ), templated_namespace );
|
||||
BOOST_CHECK_EQUAL( boost::begin( r3 ), non_templated_namespace );
|
||||
BOOST_CHECK_EQUAL( boost::begin( r4 ), non_templated_namespace );
|
||||
BOOST_CHECK_EQUAL( boost::begin( r5 ), global_namespace );
|
||||
BOOST_CHECK_EQUAL( boost::begin( r6 ), global_namespace );
|
||||
}
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_adl_conformance ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
110
test/adl_conformance_no_using.cpp
Executable file
110
test/adl_conformance_no_using.cpp
Executable file
@ -0,0 +1,110 @@
|
||||
// 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 <iostream>
|
||||
|
||||
namespace A
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename T >
|
||||
int f( const T& x )
|
||||
{
|
||||
// Default:
|
||||
std::cout << 1 << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
int adl_f2( const T& x, int* )
|
||||
{
|
||||
return f( x );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
int adl_f( const T& x )
|
||||
{
|
||||
return adl_f2( x, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
int f( const T& x )
|
||||
{
|
||||
return detail::adl_f( x );
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
int adl_f2( const T& x, int )
|
||||
{
|
||||
return detail::f( x );
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
|
||||
class C {};
|
||||
/*
|
||||
// Optional:
|
||||
int f( const C& x )
|
||||
{
|
||||
std::cout << 2 << std::endl;
|
||||
}
|
||||
*/
|
||||
template< typename T >
|
||||
class D {};
|
||||
/*
|
||||
// Optional:
|
||||
template< typename T >
|
||||
int f( const D< T >& x )
|
||||
{
|
||||
std::cout << 3 << std::endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
namespace B
|
||||
{
|
||||
class C {};
|
||||
|
||||
// Optional:
|
||||
/* int f( const C& )
|
||||
{
|
||||
std::cout << 4 << std::endl;
|
||||
}
|
||||
*/
|
||||
template< typename T >
|
||||
class D {};
|
||||
/*
|
||||
// Optional:
|
||||
template< typename T >
|
||||
int f( const D< T >& x )
|
||||
{
|
||||
std::cout << 5 << std::endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
A::f( 42 );
|
||||
|
||||
A::C ac;
|
||||
A::f( ac );
|
||||
|
||||
A::D< int > ad;
|
||||
A::f( ad );
|
||||
|
||||
B::C bc;
|
||||
A::f( bc );
|
||||
|
||||
B::D< int > bd;
|
||||
A::f( bd );
|
||||
}
|
97
test/algorithm_example.cpp
Executable file
97
test/algorithm_example.cpp
Executable file
@ -0,0 +1,97 @@
|
||||
// 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/functions.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace
|
||||
{
|
||||
//
|
||||
// example: extrating bounds in a generic algorithm
|
||||
//
|
||||
template< typename Range, typename T >
|
||||
inline typename boost::range_iterator<Range>::type
|
||||
find( Range& c, const T& value )
|
||||
{
|
||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
||||
}
|
||||
|
||||
template< typename Range, typename T >
|
||||
inline typename boost::range_const_iterator<Range>::type
|
||||
find( const Range& c, const T& value )
|
||||
{
|
||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
||||
}
|
||||
|
||||
//
|
||||
// replace first value and return its index
|
||||
//
|
||||
template< class Range, class T >
|
||||
inline typename boost::range_size<Range>::type
|
||||
my_generic_replace( Range& c, const T& value, const T& replacement )
|
||||
{
|
||||
typename boost::range_iterator<Range>::type found = find( c, value );
|
||||
|
||||
if( found != boost::end( c ) )
|
||||
*found = replacement;
|
||||
return std::distance( boost::begin( c ), found );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void check_algorithm()
|
||||
{
|
||||
//
|
||||
// usage
|
||||
//
|
||||
const unsigned N = 5;
|
||||
std::vector<int> my_vector;
|
||||
int values[] = { 1,2,3,4,5,6,7,8,9 };
|
||||
my_vector.assign( values, values + 9 );
|
||||
typedef std::vector<int>::iterator iterator;
|
||||
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
|
||||
boost::begin( my_vector ) + N );
|
||||
char str_val[] = "a string";
|
||||
char* str = str_val;
|
||||
|
||||
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3u );
|
||||
BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
|
||||
BOOST_CHECK_EQUAL( my_generic_replace( str, 'a', 'b' ), 0u );
|
||||
|
||||
}
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_algorithm ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
88
test/array.cpp
Executable file
88
test/array.cpp
Executable file
@ -0,0 +1,88 @@
|
||||
// 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/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// This should be included before "using namespace boost",
|
||||
// otherwise gcc headers will be confused with boost::iterator
|
||||
// namespace.
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
void check_array()
|
||||
{
|
||||
const int sz = 9;
|
||||
typedef int array_t[sz];
|
||||
int my_array[sz] = { 1,2,3,4,5,6,7,8,9 };
|
||||
const array_t ca = { 1,2,3,4,5,6,7,8,10 };
|
||||
|
||||
|
||||
// BOOST_RANGE_NO_STATIC_ASSERT
|
||||
#if !defined( __BORLANDC__ ) || ( _MSC_VER <= 1200 )
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<array_t>::type, int >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<array_t>::type, int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<array_t>::type, const int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<array_t>::type, std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<array_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<array_t>::type, int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const array_t>::type, const int* >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<const array_t>::type, const int >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const array_t>::type, const int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<const array_t>::type, std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<const array_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const array_t>::type, const int* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const array_t>::type, const int* >::value ));
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_EQUAL( begin( my_array ), my_array );
|
||||
BOOST_CHECK_EQUAL( end( my_array ), my_array + size( my_array ) );
|
||||
BOOST_CHECK_EQUAL( empty( my_array ), false );
|
||||
|
||||
BOOST_CHECK_EQUAL( begin( ca ), ca );
|
||||
BOOST_CHECK_EQUAL( end( ca ), ca + size( ca ) );
|
||||
BOOST_CHECK_EQUAL( empty( ca ),false );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_array ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
73
test/compat1.cpp
Executable file
73
test/compat1.cpp
Executable file
@ -0,0 +1,73 @@
|
||||
// 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/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
enum Container {};
|
||||
enum String {};
|
||||
|
||||
template< typename T >
|
||||
struct range_iterator;
|
||||
|
||||
template<>
|
||||
struct range_iterator<Container>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::iterator type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator<String>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef C type;
|
||||
};
|
||||
};
|
||||
|
||||
template< typename C >
|
||||
class iterator_of
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::BOOST_NESTED_TEMPLATE pts<C>::type type;
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
|
||||
void compat1()
|
||||
{
|
||||
std::vector<int> v;
|
||||
iterator_of< std::vector<int> >::type i = v.begin();
|
||||
}
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &compat1 ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
73
test/compat2.cpp
Executable file
73
test/compat2.cpp
Executable file
@ -0,0 +1,73 @@
|
||||
// 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/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
enum Container {};
|
||||
enum String {};
|
||||
|
||||
template< typename T >
|
||||
struct range_iterator;
|
||||
|
||||
template<>
|
||||
struct range_iterator<Container>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::iterator type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator<String>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef C type;
|
||||
};
|
||||
};
|
||||
|
||||
template< typename C >
|
||||
class iterator_of
|
||||
{
|
||||
public:
|
||||
typedef range_iterator<Container>::BOOST_NESTED_TEMPLATE pts<C>::type type;
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
|
||||
void compat1()
|
||||
{
|
||||
std::vector<int> v;
|
||||
iterator_of< std::vector<int> >::type i = v.begin();
|
||||
}
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &compat1 ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
73
test/compat3.cpp
Executable file
73
test/compat3.cpp
Executable file
@ -0,0 +1,73 @@
|
||||
// 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/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
enum Container {};
|
||||
enum String {};
|
||||
|
||||
template< typename T >
|
||||
struct range_iterator;
|
||||
|
||||
template<>
|
||||
struct range_iterator<Container>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME C::iterator type;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct range_iterator<String>
|
||||
{
|
||||
template< typename C >
|
||||
struct pts
|
||||
{
|
||||
typedef C type;
|
||||
};
|
||||
};
|
||||
|
||||
template< typename C >
|
||||
class iterator_of
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>:: template pts<C>::type type;
|
||||
};
|
||||
|
||||
#include <vector>
|
||||
|
||||
void compat1()
|
||||
{
|
||||
std::vector<int> v;
|
||||
iterator_of< std::vector<int> >::type i = v.begin();
|
||||
}
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &compat1 ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
69
test/const_ranges.cpp
Executable file
69
test/const_ranges.cpp
Executable file
@ -0,0 +1,69 @@
|
||||
// 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 <string>
|
||||
|
||||
// This should be included before "using namespace boost",
|
||||
// otherwise gcc headers will be confused with boost::iterator
|
||||
// namespace.
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
template< class T >
|
||||
const T& as_const( const T& r )
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
void check_const_ranges()
|
||||
{
|
||||
std::string foo( "foo" );
|
||||
const std::string bar( "bar" );
|
||||
|
||||
BOOST_CHECK( const_begin( foo ) == begin( as_const( foo ) ) );
|
||||
BOOST_CHECK( const_end( foo ) == end( as_const( foo ) ) );
|
||||
BOOST_CHECK( const_rbegin( foo ) == rbegin( as_const( foo ) ) );
|
||||
BOOST_CHECK( const_rend( foo ) == rend( as_const( foo ) ) );
|
||||
|
||||
BOOST_CHECK( const_begin( bar ) == begin( as_const( bar ) ) );
|
||||
BOOST_CHECK( const_end( bar ) == end( as_const( bar ) ) );
|
||||
BOOST_CHECK( const_rbegin( bar ) == rbegin( as_const( bar ) ) );
|
||||
BOOST_CHECK( const_rend( bar ) == rend( as_const( bar ) ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_const_ranges ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
100
test/iterator_pair.cpp
Executable file
100
test/iterator_pair.cpp
Executable file
@ -0,0 +1,100 @@
|
||||
// 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/functions.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
void check_iterator_pair()
|
||||
{
|
||||
typedef std::vector<int> vec_t;
|
||||
vec_t vec;
|
||||
vec.push_back( 4 );
|
||||
typedef std::pair<vec_t::iterator,vec_t::iterator>
|
||||
pair_t;
|
||||
typedef std::pair<vec_t::const_iterator,vec_t::const_iterator>
|
||||
const_pair_t;
|
||||
typedef const pair_t const_pair_tt;
|
||||
pair_t pair = std::make_pair( begin( vec ), end( vec ) );
|
||||
const_pair_t const_pair = std::make_pair( begin( vec ), end( vec ) );
|
||||
const_pair_tt constness_pair( pair );
|
||||
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<pair_t>::type,
|
||||
detail::iterator_traits<pair_t::first_type>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<pair_t>::type, pair_t::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<pair_t>::type, pair_t::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<pair_t>::type,
|
||||
detail::iterator_traits<pair_t::first_type>::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<pair_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<pair_t>::type, pair_t::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const_pair_t>::type, const_pair_t::first_type >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<const_pair_tt>::type,
|
||||
detail::iterator_traits<const_pair_t::first_type>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<const_pair_tt>::type,
|
||||
detail::iterator_traits<const_pair_tt::first_type>::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<const_pair_tt>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
|
||||
|
||||
BOOST_CHECK( begin( pair ) == pair.first );
|
||||
BOOST_CHECK( end( pair ) == pair.second );
|
||||
BOOST_CHECK( empty( pair ) == (pair.first == pair.second) );
|
||||
BOOST_CHECK( size( pair ) == std::size_t( std::distance( pair.first, pair.second ) ) );
|
||||
|
||||
BOOST_CHECK( begin( const_pair ) == const_pair.first );
|
||||
BOOST_CHECK( end( const_pair ) == const_pair.second );
|
||||
BOOST_CHECK( empty( const_pair ) == (const_pair.first == const_pair.second) );
|
||||
BOOST_CHECK( size( const_pair ) == std::size_t( std::distance( const_pair.first, const_pair.second ) ) );
|
||||
|
||||
BOOST_CHECK( begin( constness_pair ) == constness_pair.first );
|
||||
BOOST_CHECK( end( constness_pair ) == constness_pair.second );
|
||||
BOOST_CHECK( empty( constness_pair ) == (constness_pair.first == const_pair.second) );
|
||||
BOOST_CHECK( size( constness_pair ) == std::size_t( std::distance( constness_pair.first, constness_pair.second ) ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_iterator_pair ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
114
test/iterator_range.cpp
Executable file
114
test/iterator_range.cpp
Executable file
@ -0,0 +1,114 @@
|
||||
// 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/iterator_range.hpp>
|
||||
#include <boost/range/functions.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// This should be included before "using namespace boost",
|
||||
// otherwise gcc headers will be confused with boost::iterator
|
||||
// namespace.
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
struct add_one
|
||||
{
|
||||
template< class T >
|
||||
T operator()( T r ) const
|
||||
{
|
||||
return r + 1;
|
||||
}
|
||||
};
|
||||
|
||||
void check_iterator_range()
|
||||
{
|
||||
|
||||
typedef string::iterator iterator;
|
||||
typedef string::const_iterator const_iterator;
|
||||
typedef iterator_range<iterator> irange;
|
||||
typedef iterator_range<const_iterator> cirange;
|
||||
string str = "hello world";
|
||||
const string cstr = "const world";
|
||||
irange r = make_iterator_range( str );
|
||||
r = make_iterator_range( str.begin(), str.end() );
|
||||
cirange r2 = make_iterator_range( cstr );
|
||||
r2 = make_iterator_range( cstr.begin(), cstr.end() );
|
||||
r2 = make_iterator_range( str );
|
||||
|
||||
BOOST_CHECK( !r.empty() );
|
||||
BOOST_CHECK( !r2.empty() );
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
if( !(bool)r )
|
||||
BOOST_CHECK( false );
|
||||
if( !(bool)r2 )
|
||||
BOOST_CHECK( false );
|
||||
#else
|
||||
if( !r )
|
||||
BOOST_CHECK( false );
|
||||
if( !r2 )
|
||||
BOOST_CHECK( false );
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_EQUAL( r.size(), size( r ) );
|
||||
BOOST_CHECK_EQUAL( r2.size(), size( r2 ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( distance( r.begin(), r.end() ),
|
||||
distance( begin( r2 ), end( r2 ) ) );
|
||||
cout << r << r2;
|
||||
|
||||
string res = copy_range<string>( r );
|
||||
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
|
||||
|
||||
irange rr = make_iterator_range( str );
|
||||
BOOST_CHECK( rr.equal( r ) );
|
||||
|
||||
rr = make_iterator_range( str.begin(), str.begin() + 5 );
|
||||
BOOST_CHECK( rr == "hello" );
|
||||
BOOST_CHECK( rr != "hell" );
|
||||
BOOST_CHECK( rr < "hello dude" );
|
||||
BOOST_CHECK( "hello" == rr );
|
||||
BOOST_CHECK( "hell" != rr );
|
||||
BOOST_CHECK( ! ("hello dude" < rr ) );
|
||||
irange rrr = rr;
|
||||
BOOST_CHECK( rrr == rr );
|
||||
BOOST_CHECK( !( rrr != rr ) );
|
||||
BOOST_CHECK( !( rrr < rr ) );
|
||||
}
|
||||
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_iterator_range ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
113
test/partial_workaround.cpp
Executable file
113
test/partial_workaround.cpp
Executable file
@ -0,0 +1,113 @@
|
||||
// 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/config.hpp>
|
||||
#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
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/size_type.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/difference_type.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/empty.hpp>
|
||||
#include <boost/range/detail/sfinae.hpp>
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
void check_partial_workaround()
|
||||
{
|
||||
using namespace range_detail;
|
||||
using type_traits::yes_type;
|
||||
using type_traits::no_type;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// string
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
char* c_ptr;
|
||||
const char* cc_ptr;
|
||||
wchar_t* w_ptr;
|
||||
const wchar_t* cw_ptr;
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( c_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cc_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( w_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_string_impl( cw_ptr ) ) );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_char_ptr_impl( c_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_char_ptr_impl( cc_ptr ) ) );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_wchar_t_ptr_impl( w_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( no_type ) == sizeof( is_wchar_t_ptr_impl( cw_ptr ) ) );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( c_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_char_ptr_impl( cc_ptr ) ) );
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( w_ptr ) ) );
|
||||
BOOST_STATIC_ASSERT( sizeof( yes_type ) == sizeof( is_const_wchar_t_ptr_impl( cw_ptr ) ) );
|
||||
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_,
|
||||
boost::range_detail::range< vector<int> >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_pair_,
|
||||
boost::range_detail::range< pair<int,int> >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::array_,
|
||||
boost::range_detail::range< int[42] >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::char_ptr_,
|
||||
boost::range_detail::range< char* >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_char_ptr_,
|
||||
boost::range_detail::range< const char* >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::wchar_t_ptr_,
|
||||
boost::range_detail::range< wchar_t* >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::const_wchar_t_ptr_,
|
||||
boost::range_detail::range< const wchar_t* >::type >::value ));
|
||||
BOOST_STATIC_ASSERT(( boost::is_same< boost::range_detail::std_container_,
|
||||
boost::range_detail::range< vector<int> >::type >::value ));
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_partial_workaround ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
int main() { return 0; }
|
||||
|
||||
#endif
|
||||
|
104
test/reversible_range.cpp
Executable file
104
test/reversible_range.cpp
Executable file
@ -0,0 +1,104 @@
|
||||
// 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/rbegin.hpp>
|
||||
#include <boost/range/rend.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
void check_iterator()
|
||||
{
|
||||
typedef vector<char> vec_t;
|
||||
typedef vec_t::iterator iterator;
|
||||
typedef pair<iterator,iterator> pair_t;
|
||||
typedef range_reverse_iterator<pair_t>::type rev_iterator;
|
||||
typedef pair<rev_iterator,rev_iterator> rev_pair_t;
|
||||
|
||||
vec_t vec;
|
||||
pair_t p = make_pair( vec.begin(), vec.end() );
|
||||
rev_pair_t rp = make_pair( rbegin( p ), rend( p ) );
|
||||
char* str = "mutable";
|
||||
const char* cstr = "not mutable";
|
||||
char a[] = "mutable";
|
||||
const char ca[] = "not mutable";
|
||||
wchar_t* wstr = L"mutable";
|
||||
const wchar_t* cwstr= L"not mutable";
|
||||
wchar_t wa[] = L"mutable";
|
||||
const wchar_t cwa[]= L"not mutable";
|
||||
|
||||
BOOST_CHECK( rbegin( vec ) == range_reverse_iterator<vec_t>::type( vec.end() ) );
|
||||
BOOST_CHECK( rend( vec ) == range_reverse_iterator<vec_t>::type( vec.begin() ) );
|
||||
BOOST_CHECK( std::distance( rbegin( vec ), rend( vec ) ) == std::distance( begin( vec ), end( vec ) ) );
|
||||
|
||||
BOOST_CHECK( rbegin( p ) == begin( rp ) );
|
||||
BOOST_CHECK( rend( p ) == end( rp ) );
|
||||
BOOST_CHECK( std::distance( rbegin( p ), rend( p ) ) == std::distance( begin( rp ), end( rp ) ) );
|
||||
BOOST_CHECK( std::distance( begin( p ), end( p ) ) == std::distance( rbegin( rp ), rend( rp ) ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( &*begin( str ), &*( rend( str ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( str ) - 1 ), &*rbegin( str ) );
|
||||
BOOST_CHECK_EQUAL( &*begin( cstr ), &*( rend( cstr ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( cstr ) - 1 ), &*rbegin( cstr ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( &*begin( a ), &*( rend( a ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( a ) - 1 ), &*rbegin( a ) );
|
||||
BOOST_CHECK_EQUAL( &*begin( ca ), &*( rend( ca ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( ca ) - 1 ), &*rbegin( ca ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( &*begin( wstr ), &*( rend( wstr ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( wstr ) - 1 ), &*rbegin( wstr ) );
|
||||
BOOST_CHECK_EQUAL( &*begin( cwstr ), &*( rend( cwstr ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( cwstr ) - 1 ), &*rbegin( cwstr ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( &*begin( wa ), &*( rend( wa ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( wa ) - 1 ), &*rbegin( wa ) );
|
||||
BOOST_CHECK_EQUAL( &*begin( cwa ), &*( rend( cwa ) - 1 ) );
|
||||
BOOST_CHECK_EQUAL( &*( end( cwa ) - 1 ), &*rbegin( cwa ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_iterator ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
83
test/std_container.cpp
Executable file
83
test/std_container.cpp
Executable file
@ -0,0 +1,83 @@
|
||||
// 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/functions.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost;
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
void check_std_container()
|
||||
{
|
||||
typedef std::vector<int> vec_t;
|
||||
vec_t vec;
|
||||
vec.push_back( 3 ); vec.push_back( 4 );
|
||||
const vec_t cvec( vec );
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<vec_t>::type, vec_t::value_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<vec_t>::type, vec_t::iterator >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<vec_t>::type, vec_t::const_iterator >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<vec_t>::type, vec_t::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<vec_t>::type, vec_t::size_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<vec_t>::type, vec_t::iterator >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const vec_t>::type, vec_t::const_iterator >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<const vec_t>::type, vec_t::value_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<const vec_t>::type, vec_t::iterator >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<const vec_t>::type, vec_t::const_iterator >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<const vec_t>::type, vec_t::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<const vec_t>::type, vec_t::size_type >::value ));
|
||||
|
||||
BOOST_CHECK( begin( vec ) == vec.begin() );
|
||||
BOOST_CHECK( end( vec ) == vec.end() );
|
||||
BOOST_CHECK( empty( vec ) == vec.empty() );
|
||||
BOOST_CHECK( size( vec ) == vec.size() );
|
||||
|
||||
BOOST_CHECK( begin( cvec ) == cvec.begin() );
|
||||
BOOST_CHECK( end( cvec ) == cvec.end() );
|
||||
BOOST_CHECK( empty( cvec ) == cvec.empty() );
|
||||
BOOST_CHECK( size( cvec ) == cvec.size() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_std_container ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
181
test/string.cpp
Executable file
181
test/string.cpp
Executable file
@ -0,0 +1,181 @@
|
||||
// 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/functions.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
template< typename Container, typename T >
|
||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
||||
find( Container& c, T value )
|
||||
{
|
||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
||||
}
|
||||
|
||||
template< typename Container, typename T >
|
||||
BOOST_DEDUCED_TYPENAME boost::range_const_iterator<Container>::type
|
||||
find( const Container& c, T value )
|
||||
{
|
||||
return std::find( boost::begin( c ), boost::end( c ), value );
|
||||
}
|
||||
|
||||
std::vector<char>
|
||||
check_rvalue_return()
|
||||
{
|
||||
return std::vector<char>( 10, 'm' );
|
||||
}
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
void check_char()
|
||||
{
|
||||
typedef char* char_iterator_t;
|
||||
typedef char char_array_t[10];
|
||||
const char* char_s = "a string";
|
||||
char my_string[] = "another string";
|
||||
const unsigned my_string_length = 14;
|
||||
char* char_s2 = "a string";
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_iterator_t>::type,
|
||||
detail::iterator_traits<char_iterator_t>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_iterator_t>::type, char_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<char_iterator_t>::type, const char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_iterator_t>::type,
|
||||
::std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<char_iterator_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<char_iterator_t>::type, char_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const char*>::type, const char* >::value ));
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<char_array_t>::type,
|
||||
char>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<char_array_t>::type, const char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<char_array_t>::type,
|
||||
::std::ptrdiff_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<char_array_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<char_array_t>::type, char* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const char_array_t>::type, const char* >::value ));
|
||||
|
||||
BOOST_CHECK_EQUAL( begin( char_s ), char_s );
|
||||
std::size_t sz = size( char_s );
|
||||
const char* end1 = begin( char_s ) + sz;
|
||||
BOOST_CHECK_EQUAL( end( char_s ), end1 );
|
||||
BOOST_CHECK_EQUAL( empty( char_s ), (char_s == 0 || char_s[0] == char()) );
|
||||
BOOST_CHECK_EQUAL( sz, std::char_traits<char>::length( char_s ) );
|
||||
/*
|
||||
BOOST_CHECK_EQUAL( begin( char_s2 ), char_s2 );
|
||||
std::size_t sz2 = size( char_s2 );
|
||||
const char* end12 = begin( char_s2 ) + sz;
|
||||
BOOST_CHECK_EQUAL( end( char_s2 ), end12 );
|
||||
BOOST_CHECK_EQUAL( empty( char_s2 ), (char_s2 == 0 || char_s2[0] == char()) );
|
||||
BOOST_CHECK_EQUAL( sz2, std::char_traits<char>::length( char_s2 ) );
|
||||
*/
|
||||
BOOST_CHECK_EQUAL( begin( my_string ), my_string );
|
||||
range_iterator<char_array_t>::type end2 = begin( my_string ) + size( my_string );
|
||||
range_iterator<char_array_t>::type end3 = end( my_string );
|
||||
BOOST_CHECK_EQUAL( end3, end2 );
|
||||
BOOST_CHECK_EQUAL( empty( my_string ), (my_string == 0 || my_string[0] == char()) );
|
||||
BOOST_CHECK_EQUAL( size( my_string ), my_string_length );
|
||||
BOOST_CHECK_EQUAL( size( my_string ), std::char_traits<char>::length( my_string ) );
|
||||
|
||||
char to_search = 'n';
|
||||
BOOST_CHECK( find( char_s, to_search ) != end( char_s ) );
|
||||
BOOST_CHECK( find( my_string, to_search ) != end( my_string ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void check_string()
|
||||
{
|
||||
check_char();
|
||||
// check_char<volatile char>();
|
||||
// check_char<const char>();
|
||||
// check_char<const volatile char>();
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef wchar_t* wchar_iterator_t;
|
||||
const wchar_t* char_ws = L"a wide string";
|
||||
wchar_t my_wstring[] = L"another wide string";
|
||||
wchar_t* char_ws2 = L"a wide string";
|
||||
|
||||
BOOST_STATIC_ASSERT(( is_same< range_value<wchar_iterator_t>::type,
|
||||
detail::iterator_traits<wchar_iterator_t>::value_type>::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_const_iterator<wchar_iterator_t>::type, const wchar_t* >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_difference<wchar_iterator_t>::type,
|
||||
detail::iterator_traits<wchar_iterator_t>::difference_type >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_size<wchar_iterator_t>::type, std::size_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
|
||||
BOOST_STATIC_ASSERT(( is_same< range_result_iterator<const wchar_t*>::type, const wchar_t* >::value ));
|
||||
|
||||
std::size_t sz = size( char_ws );
|
||||
BOOST_CHECK_EQUAL( begin( char_ws ), char_ws );
|
||||
BOOST_CHECK_EQUAL( end( char_ws ), (begin( char_ws ) + sz) );
|
||||
BOOST_CHECK_EQUAL( empty( char_ws ), (char_ws == 0 || char_ws[0] == wchar_t()) );
|
||||
BOOST_CHECK_EQUAL( sz, std::char_traits<wchar_t>::length( char_ws ) );
|
||||
/*
|
||||
std::size_t sz2 = size( char_ws2 );
|
||||
BOOST_CHECK_EQUAL( begin( char_ws2 ), char_ws2 );
|
||||
BOOST_CHECK_EQUAL( end( char_ws2 ), (begin( char_ws2 ) + sz2) );
|
||||
BOOST_CHECK_EQUAL( empty( char_ws2 ), (char_ws2 == 0 || char_ws2[0] == wchar_t()) );
|
||||
BOOST_CHECK_EQUAL( sz2, std::char_traits<wchar_t>::length( char_ws2 ) );
|
||||
*/
|
||||
wchar_t to_search = L'n';
|
||||
BOOST_CHECK( find( char_ws, to_search ) != end( char_ws ) );
|
||||
|
||||
#if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300))
|
||||
|
||||
BOOST_CHECK( find( my_wstring, to_search ) != end( my_wstring ) );
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
find( check_rvalue_return(), 'n' );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_string ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
159
test/sub_range.cpp
Executable file
159
test/sub_range.cpp
Executable file
@ -0,0 +1,159 @@
|
||||
// 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/iterator_range.hpp>
|
||||
#include <boost/range/sub_range.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// This should be included before "using namespace boost",
|
||||
// otherwise gcc headers will be confused with boost::iterator
|
||||
// namespace.
|
||||
#include <boost/test/included/unit_test_framework.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
struct add_one
|
||||
{
|
||||
template< class T >
|
||||
T operator()( T r ) const
|
||||
{
|
||||
return r + 1;
|
||||
}
|
||||
};
|
||||
|
||||
void check_iterator_range()
|
||||
{
|
||||
|
||||
|
||||
typedef string::iterator iterator;
|
||||
typedef string::const_iterator const_iterator;
|
||||
typedef iterator_range<iterator> irange;
|
||||
typedef iterator_range<const_iterator> cirange;
|
||||
string str = "hello world";
|
||||
const string cstr = "const world";
|
||||
irange r = make_iterator_range( str );
|
||||
r = make_iterator_range( str.begin(), str.end() );
|
||||
cirange r2 = make_iterator_range( cstr );
|
||||
r2 = make_iterator_range( cstr.begin(), cstr.end() );
|
||||
r2 = make_iterator_range( str );
|
||||
|
||||
typedef sub_range<string> srange;
|
||||
typedef sub_range<const string> csrange;
|
||||
srange s = r;
|
||||
BOOST_CHECK( r == r );
|
||||
BOOST_CHECK( s == r );
|
||||
s = make_iterator_range( str );
|
||||
csrange s2 = r;
|
||||
s2 = r2;
|
||||
s2 = make_iterator_range( cstr );
|
||||
BOOST_CHECK( r2 == r2 );
|
||||
BOOST_CHECK( s2 != r2 );
|
||||
s2 = make_iterator_range( str );
|
||||
BOOST_CHECK( !(s != s) );
|
||||
|
||||
BOOST_CHECK( r.begin() == s.begin() );
|
||||
BOOST_CHECK( r2.begin()== s2.begin() );
|
||||
BOOST_CHECK( r.end() == s.end() );
|
||||
BOOST_CHECK( r2.end() == s2.end() );
|
||||
BOOST_CHECK_EQUAL( r.size(), s.size() );
|
||||
BOOST_CHECK_EQUAL( r2.size(), s2.size() );
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
if( !(bool)r )
|
||||
BOOST_CHECK( false );
|
||||
if( !(bool)r2 )
|
||||
BOOST_CHECK( false );
|
||||
if( !(bool)s )
|
||||
BOOST_CHECK( false );
|
||||
if( !(bool)s2 )
|
||||
BOOST_CHECK( false );
|
||||
#else
|
||||
if( !r )
|
||||
BOOST_CHECK( false );
|
||||
if( !r2 )
|
||||
BOOST_CHECK( false );
|
||||
if( !s )
|
||||
BOOST_CHECK( false );
|
||||
if( !s2 )
|
||||
BOOST_CHECK( false );
|
||||
#endif
|
||||
|
||||
cout << r << r2 << s << s2;
|
||||
|
||||
string res = copy_range<string>( r );
|
||||
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
|
||||
|
||||
typedef vector<char> string_type;
|
||||
string_type res2 = transform_range<string_type>( r, add_one() );
|
||||
BOOST_CHECK( res2[0] == 'i' );
|
||||
BOOST_CHECK( *res2.rbegin() == 'e' );
|
||||
|
||||
r.empty();
|
||||
s.empty();
|
||||
r.size();
|
||||
s.size();
|
||||
|
||||
irange singular_irange;
|
||||
BOOST_CHECK( singular_irange.empty() );
|
||||
BOOST_CHECK( singular_irange.size() == 0 );
|
||||
|
||||
srange singular_srange;
|
||||
BOOST_CHECK( singular_srange.empty() );
|
||||
BOOST_CHECK( singular_srange.size() == 0 );
|
||||
|
||||
BOOST_CHECK( empty( singular_irange ) );
|
||||
BOOST_CHECK( empty( singular_srange ) );
|
||||
|
||||
srange rr = make_iterator_range( str );
|
||||
BOOST_CHECK( rr.equal( r ) );
|
||||
|
||||
rr = make_iterator_range( str.begin(), str.begin() + 5 );
|
||||
BOOST_CHECK( rr == "hello" );
|
||||
BOOST_CHECK( rr != "hell" );
|
||||
BOOST_CHECK( rr < "hello dude" );
|
||||
BOOST_CHECK( "hello" == rr );
|
||||
BOOST_CHECK( "hell" != rr );
|
||||
BOOST_CHECK( ! ("hello dude" < rr ) );
|
||||
|
||||
irange rrr = rr;
|
||||
BOOST_CHECK( rrr == rr );
|
||||
BOOST_CHECK( !( rrr != rr ) );
|
||||
BOOST_CHECK( !( rrr < rr ) );
|
||||
}
|
||||
|
||||
|
||||
using boost::unit_test_framework::test_suite;
|
||||
|
||||
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||||
{
|
||||
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
|
||||
|
||||
test->add( BOOST_TEST_CASE( &check_iterator_range ) );
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user