Full merge from trunk at revision 41356 of entire boost-root tree.

[SVN r41370]
This commit is contained in:
Beman Dawes
2007-11-25 18:38:02 +00:00
parent 901266b76a
commit a33d5c22c5
31 changed files with 4352 additions and 1119 deletions

22
doc/Jamfile.v2 Normal file
View File

@ -0,0 +1,22 @@
use-project boost : $(BOOST_ROOT) ;
import boostbook : boostbook ;
import quickbook ;
xml boost_range : boost_range.qbk ;
boostbook standalone
:
boost_range
:
<xsl:param>toc.max.depth=2
<xsl:param>toc.section.depth=4
<xsl:param>chunk.section.depth=2
# <xsl:param>generate.section.toc.level=4
# <xsl:param>chunk.first.sections=7
# <xsl:param>toc.section.depth=10
;

View File

@ -31,19 +31,12 @@
<a name="overview"></a>
<h3>Overview</h3>
<p>
Four types of objects are currently supported by the library:
Three types of objects are currently supported by the library:
<ul>
<li>
standard-like containers
<li>
<code>std::pair&lt;iterator,iterator&gt;</code>
<li>
null terminated strings (this includes <code>char[]</code>,<code>wchar_t[]</code>,
<code>char*</code>, and <code>wchar_t*</code>)
<p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
<li>
built-in arrays
</li>
@ -69,17 +62,25 @@
// Single Pass Range metafunctions
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_value"><span
class=identifier>range_value</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_iterator"><span
class=identifier>range_iterator</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_const_iterator"><span
class=identifier>range_const_iterator</span></a><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>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_reference"><span
class=identifier>range_reference</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_pointer"><span
class=identifier>range_pointer</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><a href="#range_category"><span
class=identifier>range_category</span></a><span class=special>;
</span><span class=comment>//
// Forward Range metafunctions
@ -89,10 +90,6 @@ class=identifier>range_const_iterator</span></a><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>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</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
//
@ -102,55 +99,37 @@ class=identifier>range_size</span></a><span class=special>;
href="#range_reverse_iterator"><span
class=identifier>range_reverse_iterator</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>struct </span><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>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</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>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</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>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#begin"><span class=identifier>begin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#end"><span class=identifier>end</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>bool
</span><a href="#empty"><span class=identifier>empty</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><a href="#empty"><span class=identifier>empty</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=comment>//
// Forward Range functions
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_size</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#size"><span class=identifier>size</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_difference</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#size"><span class=identifier>distance</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=comment>//
// Bidirectional Range functions
@ -158,41 +137,69 @@ class=identifier>range_reverse_result_iterator</span></a><span class=special>;
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rbegin"><span class=identifier>rbegin</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#rend"><span class=identifier>rend</span></a><span class=special>( </span><span class=keyword>const </span><span
class=identifier>T</span><span class=special>&amp; </span><span class=identifier>c </span><span class=special>);
class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
</span><span class=comment>//
// Random Access Range functions
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword></span><span class=keyword>typename </span><span class=identifier>range_difference</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type
</span><a href="#size"><span class=identifier>size</span></a><span class=special>( </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);</span>
<span class=comment>//
// Special const Range functions
//
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;</span>
<span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type </span>
<span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</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>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;</span>
<span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type </span>
<span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</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>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;</span>
<span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type </span>
<span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</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>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;</span>
<span class=keyword>typename </span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type </span>
<span class=keyword>typename </span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&gt;::</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>&amp; </span><span class=identifier>r </span><span class=special>);</span>
<span class=comment>//
// String utilities
//</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt;...</span><span class=identifier>see</span> <span class=identifier>below</span><span class=special>...&gt;</span>
<span class=identifier><a href="#as_literal">as_literal</a></span><span class=special>(</span> <span class=identifier>T</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt;...</span><span class=identifier>see</span> <span class=identifier>below</span><span class=special>...&gt;</span>
<span class=identifier><a href="#as_array">as_literal</a></span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>T</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt;</span> <span class=keyword>typename</span> <span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=special>&gt;</span>
<span class=identifier><a href="#as_array">as_array</a></span><span class=special>(</span> <span class=identifier>T</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt;</span> <span class=keyword>typename</span> <span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=special>&gt;</span>
<span class=identifier><a href="#as_literal">as_array</a></span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>T</span><span class=special>&amp;</span> <span class=identifier>r</span> <span class=special>);</span>
<span class=special>} </span><span class=comment>// namespace 'boost'
</span>
</pre>
@ -252,88 +259,79 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<th>
Complexity</th>
</tr>
<tr>
<a name="range_value"></a>
<td><code>range_value&lt;X&gt;::type</code></td>
<td><code>T::value_type</code><br>
<code>boost::iterator_value&lt;P::first_type&gt;::type</code> <!--if <code>P</code> is an instantiation of <code>std::pair</code>--><br>
<code>A</code><br>
<code>Char</code>
<td>compile time</td>
</tr>
<tr>
<a name="range_iterator"></a>
<td><code>range_iterator&lt;X&gt;::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&lt;X&gt;::type</code></td>
<td><code>range_iterator&lt;const X&gt;::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_value"></a>
<td><code>range_value&lt;X&gt;::type</code></td>
<td><code>boost::iterator_value&lt;range_iterator&lt;X&gt;::type&gt;::type</code>
</td>
<td>compile time</td>
</tr>
<tr>
<a name="range_reference"></a>
<td><code>range_reference&lt;X&gt;::type</code></td>
<td><code>boost::iterator_reference&lt;range_iterator&lt;X&gt;::type&gt;::type</code>
</td>
<td>compile time</td>
</tr>
<tr>
<a name="range_pointer"></a>
<td><code>range_pointer&lt;X&gt;::type</code></td>
<td><code>boost::iterator_pointer&lt;range_iterator&lt;X&gt;::type&gt;::type</code>
</td>
<td>compile time</td>
</tr>
<tr>
<a name="range_category"></a>
<td><code>range_category&lt;X&gt;::type</code></td>
<td><code>boost::iterator_category&lt;range_iterator&lt;X&gt;::type&gt;::type</code>
</td>
<td>compile time</td>
</tr>
<tr>
<a name="range_difference"></a>
<td><code>range_difference&lt;X&gt;::type</code></td>
<td><code>T::difference_type</code><br>
<code>boost::iterator_difference&lt;P::first_type&gt;::type</code><br>
<code>std::ptrdiff_t</code><br>
<code>std::ptrdiff_t</code><br>
<td>
<code>boost::iterator_difference&lt;range_iterator&lt;X&gt;::type&gt;::type</code></td>
<td>compile time</td>
</tr>
<tr>
<a name="range_size"></a>
<td><code>range_size&lt;X&gt;::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&lt;X&gt;::type</code></td>
<td><code>range_const_iterator&lt;X&gt;::type</code> if <code>X</code> is <code>const</code>
<br>
<code>range_iterator&lt;X&gt;::type</code> otherwise
</td>
<td>compile time</td>
</tr>
<tr>
<a name="range_reverse_iterator"></a>
<td><code>range_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt; typename range_iterator&lt;T&gt;::type &gt;</code><br>
<td><code>boost::reverse_iterator&lt;range_iterator&lt;X&gt;::type&gt;</code><br>
<td>compile time</td>
</tr>
<tr>
<a name="range_const_reverse_iterator"></a>
<td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt; typename range_const_iterator&lt;T&gt;::type &gt;</code>
<td><code>range_reverse_iterator&lt;const X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt;range_iterator&lt;const X&gt;::type&gt;</code>
<br>
<td>compile time</td>
</tr>
<tr>
<a name="range_reverse_result_iterator"></a>
<td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td><code>boost::reverse_iterator&lt; typename range_result_iterator&lt;T&gt;::type
&gt;</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">
@ -350,12 +348,11 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<tr>
<a name="begin"></a>
<td><code>begin(x)</code></td>
<td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td><code>range_iterator&lt;X&gt;::type</code></td>
<td>
<code>p.first</code> if <code>p</code> is of type <code>std::pair&ltT&gt;<code><br>
<code>a</code> if <code>a</code> is an array <br>
<code>s</code> if <code>s</code> is a string literal<br>
<code>boost_range_begin(x)</code> if that expression would invoke a function found by ADL <br>
<code>range_begin(x)</code> if that expression would invoke a function found by ADL <br>
<code>t.begin()</code> otherwise
<td>constant time</td>
@ -363,106 +360,155 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<tr>
<a name="end"></a>
<td><code>end(x)</code></td>
<td><code>range_result_iterator&lt;X&gt;::type</code></td>
<td><code>range_iterator&lt;X&gt;::type</code></td>
<td>
<code>p.second</code> if <code>p</code> is of type <code>std::pair&ltT&gt;<code><br>
<code>a + sz</code> if <code>a</code> is an array of size <code>sz</code><br>
<code>s + std::char_traits&lt;X&gt;::length( s )</code> if <code>s</code> is a <code>Char*</code>
<code>a + sz</code> if <code>a</code> is an array of size <code>sz</code>
<br>
<code>s + sz - 1</code> if <code>s</code> is a string literal of size <code>sz</code>
<br>
<code>boost_range_end(x)</code> if that expression would invoke a function found by ADL <br>
<code>range_end(x)</code> if that expression would invoke a function found by ADL <br>
<code>t.end()</code> otherwise
<td>linear if <code>X</code> is <code>Char*</code>
<br>
constant time otherwise</td>
<td>
constant time </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><code>boost::begin(x) == boost::end(x)</code><br>
<td> constant time <br>
</td>
</tr>
<tr>
<a name="distance"></a>
<td><code>distance(x)</code></td>
<td><code>range_difference&lt;X&gt;::type</code></td>
<td>
<code>
std::distance(boost::begin(x),boost::end(x))
</code>
</td>
<td>-</td>
</tr>
<tr>
<a name="size"></a>
<td><code>size(x)</code></td>
<td><code>range_size&lt;X&gt;::type</code></td>
<td>
<code>std::distance(p.first,p.second)</code> if <code>p</code> is of type <code>std::pair&ltT&gt;<code><br>
<code>sz</code> if <code>a</code> is an array of size <code>sz</code><br>
<code>end(s) - s</code> if <code>s</code> is a string literal or a <code>Char*</code><br>
<code>boost_range_size(x)</code> if that expression would invoke a function found by ADL <br>
<code>t.size()</code> otherwise
<td>linear if <code>X</code> is <code>Char*</code>
<br>
or if <code>std::distance()</code> is linear
<br>
constant time otherwise</td>
<td><code>range_difference&lt;X&gt;::type</code></td>
<td><code> boost::end(x) - boost::begin(x)</code>
<td> constant time </td>
</tr>
<tr>
<a name="rbegin"></a>
<td><code>rbegin(x)</code></td>
<td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td><code>range_reverse_result_iterator&lt;X&gt;::type( end(x) )</code>
<td><code>range_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>range_reverse_iterator&lt;X&gt;::type( boost::end(x) )</code>
<br>
<td>same as <code>end(x)</code>
<td>constant time
</td>
</tr>
<tr>
<a name="rend"></a>
<td><code>rend(x)</code></td>
<td><code>range_reverse_result_iterator&lt;X&gt;::type</code></td>
<td><code>range_reverse_result_iterator&lt;X&gt;::type( begin(x) )</code>
<td>same as <code>begin(x)</code></td>
<td><code>range_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>range_reverse_iterator&lt;X&gt;::type( boost::begin(x) )</code>
<td>constant time</td>
</tr>
<tr>
<a name="const_begin"></a>
<td><code>const_begin(x)</code></td>
<td><code>range_const_iterator&lt;X&gt;::type</code></td>
<td><code>range_const_iterator&lt;X&gt;::type( begin(x) )</code>
<td><code>range_iterator&lt;const X&gt;::type</code></td>
<td><code>range_iterator&lt;const X&gt;::type( boost::begin(x) )</code>
<br>
<td>same as <code>begin(x)</code>
<td>constant time
</td>
</tr>
<tr>
<a name="const_end"></a>
<td><code>const_end(x)</code></td>
<td><code>range_const_iterator&lt;X&gt;::type</code></td>
<td><code>range_const_iterator&lt;X&gt;::type( end(x) )</code>
<td>same as <code>end(x)</code></td>
<td><code>range_iterator&lt;const X&gt;::type</code></td>
<td><code>range_iterator&lt;const X&gt;::type( boost::end(x) )</code>
<td>constant time</td>
</tr>
<tr>
<a name="const_rbegin"></a>
<td><code>const_rbegin(x)</code></td>
<td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>range_const_reverse_iterator&lt;X&gt;::type( rbegin(x) )</code>
<td><code>range_reverse_iterator&lt;const X&gt;::type</code></td>
<td><code>range_reverse_iterator&lt;const X&gt;::type( boost::rbegin(x) )</code>
<br>
<td>same as <code>rbegin(x)</code>
<td>constant time
</td>
</tr>
<tr>
<a name="const_rend"></a>
<td><code>const_rend(x)</code></td>
<td><code>range_const_reverse_iterator&lt;X&gt;::type</code></td>
<td><code>range_const_reverse_iterator&lt;X&gt;::type( rend(x) )</code>
<td>same as <code>rend(x)</code></td>
<td><code>range_reverse_iterator&lt;const X&gt;::type</code></td>
<td><code>range_reverse_iterator&lt;const X&gt;::type( boost::rend(x) )</code>
<td>constant time</td>
</tr>
<tr>
<a name="as_literal"></a>
<td><code>as_literal(x)</code></td>
<td><code>iterator_range&lt;U></code> where <code>U</code> is
<code>Char*</code> if <code>x</code> is a pointer to a
string and <code>U</code> is
<code>range_iterator&lt;X>::type</code> otherwise
</td>
<td>
<code>[a,a+sz-1)</code> if <code>a</code> is an array of size <code>sz</code><br>
<code>[s,s + std::char_traits&lt;X&gt;::length(s))</code> if <code>s</code> is a <code>Char*</code>
<br>
<code>[boost::begin(x),boost::end(x))</code> otherwise
</td>
<td>linear time for pointers to a string, constant time
otherwise</td>
</tr>
<tr>
<a name="as_array"></a>
<td><code>as_array(x)</code></td>
<td><code>iterator_range&lt;X></code> </td>
<td>
<code>[boost::begin(x),boost::end(x))</code>
</td>
<td>constant time otherwise</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.
The special <code>const_</code>-named functions are useful when you
want to document clearly that your code is read-only.
</p>
<p>
<code>as_literal()</code> can be used <i>internally</i> in string
algorithm librararies to such that arrays of characters are
handled correctly.
</p>
<p>
<code>as_array()</code> can be used with string algorithm libraries to make it clear that arrays of characters are handled like an array and not like a string.
</p>
<p>Notice that the above functions should always be called with
qualification (<code>boost::</code>) to prevent <i>unintended</i>
Argument Dependent Lookup (ADL).
</p>
<hr>
<a name="minimal_interface"></a>
<h3>Extending the library</h3>
<ul>
<li><a href="#method1">Method 1: provide member functions and nested types</a></li>
<li><a href="#method2">Method 2: provide free-standing functions and specialize metafunctions</a></li>
</ul>
@ -499,10 +545,6 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
</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>
@ -528,10 +570,6 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<td><code>const_iterator</code></td>
<td><a href="range.html#single_pass_range">Single Pass 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>
@ -562,26 +600,23 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<th>
Related concept</th>
<tr>
<td><code>boost_range_begin(x)</code></td>
<td><code>range_begin(x)</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost_range_end(x)</code>
<td><code>range_end(x)</code>
</td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost_range_size(x)</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p><code>boost_range_begin()</code> and <code>boost_range_end()</code> must be
<p><code>range_begin()</code> and <code>range_end()</code> must be
overloaded for both <code>const</code> and mutable reference arguments.
</p>
<p>
You must also specialize 3 metafunctions for your type <code>X</code>:
You must also specialize two metafunctions for your type <code>X</code>:
</p>
<p>
<table cellpadding="5" border="1" ID="Table2">
@ -591,17 +626,14 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<th>
Related concept</th>
<tr>
<td><code>boost::range_iterator</code></td>
<td><code>boost::range_mutable_iterator</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost::range_const_iterator</code></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a></td>
</tr>
<tr>
<td><code>boost::range_size</code></td>
<td><a href="range.html#forward_range">Forward Range</a></td>
</tr>
</table>
</p>
<p>
@ -635,7 +667,7 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
//</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>range_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>range_mutable_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>T</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
@ -644,20 +676,13 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<span class=keyword>struct</span> <span class=identifier>range_const_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=comment>//
// Remark: this is defined similar to 'range_iterator'
// Remark: this is defined similar to 'range_mutable_iterator'
// because the 'Pair' type does not distinguish
// between an iterator and a const_iterator.
//</span>
<span class=keyword>typedef</span> <span class=identifier>T</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>type</span><span class=special>;</span>
<span class=special>};</span>
<span class=special>}</span> <span class=comment>// namespace 'boost'</span>
<span class=keyword>namespace</span> <span class=identifier>Foo</span>
@ -669,36 +694,29 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
//</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_begin</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>range_begin</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_begin</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>range_begin</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_end</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>range_end</span><span class=special>(</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>boost_range_end</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=keyword>inline</span> <span class=identifier>T</span> <span class=identifier>range_end</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>;</span>
<span class=special>}</span>
<span class=keyword>template</span><span class=special>&lt;</span> <span class=keyword>class</span> <span class=identifier>T</span> <span class=special>&gt;</span>
<span class=keyword>inline</span> <span class=keyword>typename</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>boost_range_size</span><span class=special>(</span> <span class=keyword>const</span> <span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span> <span class=special>)</span>
<span class=special>{</span>
<span class=keyword>return</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>distance</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>first</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>last</span><span class=special>);</span>
<span class=special>}</span>
<span class=special>}</span> <span class=comment>// namespace 'Foo'</span>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&gt;</span>
@ -716,9 +734,9 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<span class=identifier>iter</span> <span class=identifier>e</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>i</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>e</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_size</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>s</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>size</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_difference</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>s</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>size</span><span class=special>(</span> <span class=identifier>pair</span> <span class=special>);</span>
<span class=identifier>s</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>size</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_const_reverse_iterator</span><span class=special>&lt;</span> <span class=identifier>Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_reverse_iterator</span><span class=special>&lt;</span> <span class=identifier>const Foo</span><span class=special>::</span><span class=identifier>Pair</span><span class=special>&lt;</span><span class=identifier>iter</span><span class=special>&gt;</span> <span class=special>&gt;::</span><span class=identifier>type</span>
<span class=identifier>ri</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>rbegin</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>),</span>
<span class=identifier>re</span> <span class=special>=</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>rend</span><span class=special>(</span> <span class=identifier>cpair</span> <span class=special>);</span>
<span class=special>}</span>
@ -727,7 +745,7 @@ class=identifier>T</span><span class=special>&amp; </span><span class=identifier
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2007
</p>
<br>
<br>

1234
doc/boost_range.qbk Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,3 @@
/*
// Copyright Thorsten Ottosen 2003-2005. 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)
*/
#include <boost/range.hpp>
#include <iterator> // for std::iterator_traits, std::distance()

View File

@ -26,10 +26,6 @@
</li>
shows how to implement a container version of <code >std::find()</code> that
works with <code >char[],wchar_t[],char*,wchar_t*.</code>
<p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
<li >
<a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a>
@ -47,7 +43,7 @@
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>

View File

@ -116,7 +116,7 @@ Cool indeed!
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>

View File

@ -50,6 +50,12 @@
>range_iterator</a></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
</tr>
<tr >
<td ><code >&lt;boost/range/mutable_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_mutable_iterator"
>range_mutable_iterator</a></td>
<td><a href="range.html#single_pass_range">Single Pass Range</a> </td>
</tr>
<tr >
<td ><code >&lt;boost/range/const_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_const_iterator"
@ -63,31 +69,23 @@
<td><a href="range.html#forward_range">Forward Range</a> </td>
</tr>
<tr >
<td ><code >&lt;boost/range/size_type.hpp&gt;</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 >&lt;boost/range/result_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_result_iterator"
>range_result_iterator</a></td>
<td ><code >&lt;boost/range/pointer.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_pointer"
>range_pointer</a></td>
<td>- </td>
</tr>
<tr >
<td ><code >&lt;boost/range/category.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_category"
>range_category</a></td>
<td>- </td>
</tr>
<tr >
<td ><code >&lt;boost/range/reverse_iterator.hpp&gt;</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 >&lt;boost/range/const_reverse_iterator.hpp&gt;</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 >&lt;boost/range/reverse_result_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#range_reverse_result_iterator">range_reverse_result_iterator</a></td>
<td>- </td>
</tr>
<tr >
<td ><code >&lt;boost/range/begin.hpp&gt;</code></td>
<td >
@ -109,10 +107,16 @@
<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 >&lt;boost/range/distance.hpp&gt;</code></td>
<td ><a href="boost_range.html#distance" >distance</a></td>
<td><a href="range.html#forward_range">Forward Range</a> </td>
</tr>
<tr >
<td ><code >&lt;boost/range/size.hpp&gt;</code></td>
<td ><a href="boost_range.html#size" >size</a></td>
<td><a href="range.html#forward_range">Forward Range</a> </td>
<td><a href="range.html#random_access_range">Random Access Range</a>
</td>
</tr>
<tr >
<td ><code >&lt;boost/range/rbegin.hpp&gt;</code></td>
@ -130,6 +134,21 @@
</td>
<td><a href="range.html#bidirectional_range">Bidirectional Range</a> </td>
</tr>
<tr >
<td ><code >&lt;boost/range/as_array.hpp&gt;</code></td>
<td >
<a href="boost_range.html#as_array" >as_array</a>
</td>
<td>-</td>
</tr>
<tr >
<td ><code >&lt;boost/range/as_literal.hpp&gt;</code></td>
<td >
<a href="boost_range.html#as_literal" >as_literal</a>
</td>
<td>-</td>
</tr>
<tr >
<td ><code >&lt;boost/range/iterator_range.hpp&gt;</code></td>
<td ><a href="utility_class.html#iter_range"
@ -154,7 +173,7 @@
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2007
</p>
<br>

View File

@ -61,7 +61,7 @@ C++ standard: <blockquote>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2006
</p>
<br>

View File

@ -35,16 +35,14 @@
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.
works with containers, provided a suitable adapter is used.
</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.
containers, <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/refmanual/metafunction.html">metafunctions</a> and
free-standing functions so syntactic and/or semantic differences can be removed.
@ -60,22 +58,14 @@ free-standing functions so syntactic and/or semantic differences can be removed.
more flexible, compact and maintainable client code
</li>
<li >
correct handling of null-terminated strings
<p>
<b>Warning:</b><i> support for null-terminated strings is deprecated and will
disappear in the next Boost release (1.34). </i>
</p>
safe use of built-in arrays
</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>
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>
//
@ -89,7 +79,7 @@ free-standing functions so syntactic and/or semantic differences can be removed.
</span><span class=special>}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_const_iterator</span><span class=special>&lt; </span><span
</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>&lt; </span><span class=keyword>const </span><span
class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>find</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardReadableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value </span><span class=special>)
</span><span class=special>{
@ -100,7 +90,7 @@ class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><s
// replace first value and return its index
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_size</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_difference</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>replacement </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>range_iterator</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>found </span><span class=special>= </span><span class=identifier>find</span><span class=special>( </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>value </span><span class=special>);
@ -146,7 +136,7 @@ Notice that we have to
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2007
</p>
<br>

581
doc/mfc_atl.html Normal file
View File

@ -0,0 +1,581 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.10: http://docutils.sourceforge.net/" />
<title>Boost Range MFC/ATL Extension</title>
<meta name="author" content="Shunsuke Sogame" />
<meta name="date" content="26th of May 2006" />
<meta name="copyright" content="Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt)." />
<style type="text/css">
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:Date: $Date: 2005-09-25 17:49:54 +0200 (Sun, 25 Sep 2005) $
:Revision: $Revision: 3901 $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* "! important" is used here to override other ``margin-top`` and
``margin-bottom`` styles that are later in the stylesheet or
more specific. See http://www.w3.org/TR/CSS1#the-cascade */
.first {
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin-left: 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left {
clear: left }
img.align-right {
clear: right }
img.borderless {
border: 0 }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid thin gray }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid thin black }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
tt.docutils {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="boost-range-mfc-atl-extension">
<h1 class="title"><img alt="Boost" src="http://www.boost.org/libs/ptr_container/doc/boost.png" /> Range MFC/ATL Extension</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Shunsuke Sogame</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference" href="mailto:mb2act&#64;yahoo.co.jp">mb2act&#64;yahoo.co.jp</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>26th of May 2006</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">LICENSE_1_0.txt</a>).</td></tr>
</tbody>
</table>
<div class="section">
<h1><a id="overview" name="overview">Overview</a></h1>
<p>Boost.Range MFC/ATL Extension provides <a class="reference" href="../index.html">Boost.Range</a> support for MFC/ATL collection and string types.</p>
<pre class="literal-block">
CTypedPtrArray&lt;CPtrArray, CList&lt;CString&gt; *&gt; myArray;
...
BOOST_FOREACH (CList&lt;CString&gt; *theList, myArray)
{
BOOST_FOREACH (CString&amp; str, *theList)
{
boost::to_upper(str);
std::sort(boost::begin(str), boost::end(str));
...
}
}
</pre>
<ul class="simple">
<li><a class="reference" href="#requirements">Requirements</a></li>
<li><a class="reference" href="#mfc-ranges">MFC Ranges</a></li>
<li><a class="reference" href="#atl-ranges">ATL Ranges</a></li>
<li><a class="reference" href="#const-ranges">const Ranges</a></li>
<li><a class="reference" href="#references">References</a></li>
</ul>
</div>
<div class="section">
<h1><a id="requirements" name="requirements">Requirements</a></h1>
<ul class="simple">
<li><a class="reference" href="http://www.boost.org/">Boost C++ Libraries Version 1.34.0</a> or later (no compilation required)</li>
<li>Visual C++ 7.1 or Visual C++ 8.0</li>
</ul>
</div>
<div class="section">
<h1><a id="mfc-ranges" name="mfc-ranges">MFC Ranges</a></h1>
<p>If the <tt class="docutils literal"><span class="pre">&lt;boost/range/mfc.hpp&gt;</span></tt> is included before or after <a class="reference" href="../index.html">Boost.Range</a> headers,
the MFC collections and strings become models of Range.
The table below lists the Traversal Category and <tt class="docutils literal"><span class="pre">range_reference</span></tt> of MFC ranges.</p>
<table border="1" class="docutils">
<colgroup>
<col width="34%" />
<col width="21%" />
<col width="45%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><tt class="docutils literal"><span class="pre">Range</span></tt></th>
<th class="head">Traversal Category</th>
<th class="head"><tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt></th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">CArray&lt;T,A&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CList&lt;T,A&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMap&lt;K,AK,M,AM&gt;</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrArray&lt;B,T*&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">T*</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrList&lt;B,T*&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">T*</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CTypedPtrMap&lt;B,T*,V*&gt;</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;T*,V*&gt;</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CByteArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">BYTE&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CDWordArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">DWORD&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CObArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">CObject*</span> <span class="pre">&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CPtrArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">void*</span> <span class="pre">&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CStringArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">CString&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CUIntArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">UINT&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CWordArray</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">WORD&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CObList</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">CObject*</span> <span class="pre">&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CPtrList</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">void*</span> <span class="pre">&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CStringList</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">CString&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapPtrToWord</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;void*,WORD&gt;</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapPtrToPtr</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;void*,void*&gt;</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapStringToOb</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;String,CObject*&gt;</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapStringToString</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapWordToOb</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;WORD,CObject*&gt;</span> <span class="pre">const</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CMapWordToPtr</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;WORD,void*&gt;</span> <span class="pre">const</span></tt></td>
</tr>
</tbody>
</table>
<p>Other <a class="reference" href="../index.html">Boost.Range</a> metafunctions are defined by the following.
Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.
<tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">remove_reference&lt;remove_const&lt;Ref&gt;::type&gt;::type</span></tt>,
<tt class="docutils literal"><span class="pre">range_difference&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
<tt class="docutils literal"><span class="pre">range_pointer&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;Ref&gt;::type&gt;::type</span></tt>.
As for <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Range</span></tt>, see <a class="reference" href="#const-ranges">const Ranges</a>.</p>
</div>
<div class="section">
<h1><a id="atl-ranges" name="atl-ranges">ATL Ranges</a></h1>
<p>If the <tt class="docutils literal"><span class="pre">&lt;boost/range/atl.hpp&gt;</span></tt> is included before or after <a class="reference" href="../index.html">Boost.Range</a> headers,
the ATL collections and strings become models of Range.
The table below lists the Traversal Category and <tt class="docutils literal"><span class="pre">range_reference</span></tt> of ATL ranges.</p>
<table border="1" class="docutils">
<colgroup>
<col width="34%" />
<col width="21%" />
<col width="45%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head"><tt class="docutils literal"><span class="pre">Range</span></tt></th>
<th class="head">Traversal Category</th>
<th class="head"><tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt></th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">CAtlArray&lt;E,ET&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CAutoPtrArray&lt;E&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CInterfaceArray&lt;I,pi&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">CComQIPtr&lt;I,pi&gt;&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CAtlList&lt;E,ET&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CAutoPtrList&lt;E&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CHeapPtrList&lt;E,A&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">E&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CInterfaceList&lt;I,pi&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">CComQIPtr&lt;I,pi&gt;&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CAtlMap&lt;K,V,KT,VT&gt;</span></tt></td>
<td>Forward</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CRBTree&lt;K,V,KT,VT&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CRBMap&lt;K,V,KT,VT&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CRBMultiMap&lt;K,V,KT,VT&gt;</span></tt></td>
<td>Bidirectional</td>
<td><tt class="docutils literal"><span class="pre">Range::CPair&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CSimpleStringT&lt;B,b&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CStringT&lt;B,ST&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CFixedStringT&lt;S,n&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">range_reference&lt;S&gt;::type</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CStringT&lt;B,ST&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">B&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CComBSTR</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">OLECHAR&amp;</span></tt></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">CSimpleArray&lt;T,TE&gt;</span></tt></td>
<td>Random Access</td>
<td><tt class="docutils literal"><span class="pre">T&amp;</span></tt></td>
</tr>
</tbody>
</table>
<p>Other <a class="reference" href="../index.html">Boost.Range</a> metafunctions are defined by the following.
Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.
<tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">remove_reference&lt;Ref&gt;::type</span></tt>,
<tt class="docutils literal"><span class="pre">range_difference&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
<tt class="docutils literal"><span class="pre">range_pointer&lt;Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;Ref&gt;::type&gt;::type</span></tt>.
As for <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Range</span></tt>, see <a class="reference" href="#const-ranges">const Ranges</a>.</p>
</div>
<div class="section">
<h1><a id="const-ranges" name="const-ranges">const Ranges</a></h1>
<p><tt class="docutils literal"><span class="pre">range_reference&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is defined by the following algorithm.
Let <tt class="docutils literal"><span class="pre">Range</span></tt> be any type listed above and <tt class="docutils literal"><span class="pre">ReF</span></tt> be the same as <tt class="docutils literal"><span class="pre">range_reference&lt;Range&gt;::type</span></tt>.</p>
<pre class="literal-block">
if (Range is CObArray || Range is CObList)
return CObject const * &amp;
else if (Range is CPtrArray || Range is CPtrList)
return void const * &amp;
else if (there is a type X such that X&amp; is the same as ReF)
return X const &amp;
else if (there is a type X such that X* const is the same as ReF)
return X const * const
else
return ReF
</pre>
<p>Other <a class="reference" href="../index.html">Boost.Range</a> metafunctions are defined by the following.
<tt class="docutils literal"><span class="pre">range_value&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">range_value&lt;Range&gt;::type</span></tt>,
<tt class="docutils literal"><span class="pre">range_difference&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">std::ptrdiff_t</span></tt>, and
<tt class="docutils literal"><span class="pre">range_pointer&lt;const</span> <span class="pre">Range&gt;::type</span></tt> is the same as <tt class="docutils literal"><span class="pre">add_pointer&lt;remove_reference&lt;range_reference&lt;const</span> <span class="pre">Range&gt;::type&gt;::type&gt;::type</span></tt>.</p>
</div>
<div class="section">
<h1><a id="references" name="references">References</a></h1>
<ul class="simple">
<li><a class="reference" href="../index.html">Boost.Range</a></li>
<li><a class="reference" href="http://msdn2.microsoft.com/en-us/library/942860sh.aspx">MFC Collections</a></li>
<li><a class="reference" href="http://msdn2.microsoft.com/en-US/library/15e672bd.aspx">ATL Collection Classes</a></li>
</ul>
</div>
</div>
</body>
</html>

232
doc/mfc_atl.rst Normal file
View File

@ -0,0 +1,232 @@
++++++++++++++++++++++++++++++++
|Boost| Range MFC/ATL Extension
++++++++++++++++++++++++++++++++
.. |Boost| image:: http://www.boost.org/libs/ptr_container/doc/boost.png
:Author: Shunsuke Sogame
:Contact: mb2act@yahoo.co.jp
:date: 26th of May 2006
:copyright: Shunsuke Sogame 2005-2006. Use, modification and distribution is subject to the Boost Software License, Version 1.0 (see LICENSE_1_0.txt__).
__ http://www.boost.org/LICENSE_1_0.txt
========
Overview
========
Boost.Range MFC/ATL Extension provides `Boost.Range`_ support for MFC/ATL collection and string types.
.. parsed-literal::
CTypedPtrArray<CPtrArray, CList<CString> \*> myArray;
...
BOOST_FOREACH (CList<CString> \*theList, myArray)
{
BOOST_FOREACH (CString& str, \*theList)
{
boost::to_upper(str);
std::sort(boost::begin(str), boost::end(str));
...
}
}
* `Requirements`_
* `MFC Ranges`_
* `ATL Ranges`_
* `const Ranges`_
* `References`_
============
Requirements
============
- `Boost C++ Libraries Version 1.34.0`__ or later (no compilation required)
- Visual C++ 7.1 or Visual C++ 8.0
__ Boost_
==========
MFC Ranges
==========
If the ``<boost/range/mfc.hpp>`` is included before or after `Boost.Range`_ headers,
the MFC collections and strings become models of Range.
The table below lists the Traversal Category and ``range_reference`` of MFC ranges.
============================= ================== =======================================
``Range`` Traversal Category ``range_reference<Range>::type``
============================= ================== =======================================
``CArray<T,A>`` Random Access ``T&``
----------------------------- ------------------ ---------------------------------------
``CList<T,A>`` Bidirectional ``T&``
----------------------------- ------------------ ---------------------------------------
``CMap<K,AK,M,AM>`` Forward ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CTypedPtrArray<B,T*>`` Random Access ``T* const``
----------------------------- ------------------ ---------------------------------------
``CTypedPtrList<B,T*>`` Bidirectional ``T* const``
----------------------------- ------------------ ---------------------------------------
``CTypedPtrMap<B,T*,V*>`` Forward ``std::pair<T*,V*> const``
----------------------------- ------------------ ---------------------------------------
``CByteArray`` Random Access ``BYTE&``
----------------------------- ------------------ ---------------------------------------
``CDWordArray`` Random Access ``DWORD&``
----------------------------- ------------------ ---------------------------------------
``CObArray`` Random Access ``CObject* &``
----------------------------- ------------------ ---------------------------------------
``CPtrArray`` Random Access ``void* &``
----------------------------- ------------------ ---------------------------------------
``CStringArray`` Random Access ``CString&``
----------------------------- ------------------ ---------------------------------------
``CUIntArray`` Random Access ``UINT&``
----------------------------- ------------------ ---------------------------------------
``CWordArray`` Random Access ``WORD&``
----------------------------- ------------------ ---------------------------------------
``CObList`` Bidirectional ``CObject* &``
----------------------------- ------------------ ---------------------------------------
``CPtrList`` Bidirectional ``void* &``
----------------------------- ------------------ ---------------------------------------
``CStringList`` Bidirectional ``CString&``
----------------------------- ------------------ ---------------------------------------
``CMapPtrToWord`` Forward ``std::pair<void*,WORD> const``
----------------------------- ------------------ ---------------------------------------
``CMapPtrToPtr`` Forward ``std::pair<void*,void*> const``
----------------------------- ------------------ ---------------------------------------
``CMapStringToOb`` Forward ``std::pair<String,CObject*> const``
----------------------------- ------------------ ---------------------------------------
``CMapStringToString`` Forward ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CMapWordToOb`` Forward ``std::pair<WORD,CObject*> const``
----------------------------- ------------------ ---------------------------------------
``CMapWordToPtr`` Forward ``std::pair<WORD,void*> const``
============================= ================== =======================================
Other `Boost.Range`_ metafunctions are defined by the following.
Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
``range_value<Range>::type`` is the same as ``remove_reference<remove_const<Ref>::type>::type``,
``range_difference<Range>::type`` is the same as ``std::ptrdiff_t``, and
``range_pointer<Range>::type`` is the same as ``add_pointer<remove_reference<Ref>::type>::type``.
As for ``const Range``, see `const Ranges`_.
==========
ATL Ranges
==========
If the ``<boost/range/atl.hpp>`` is included before or after `Boost.Range`_ headers,
the ATL collections and strings become models of Range.
The table below lists the Traversal Category and ``range_reference`` of ATL ranges.
============================= ================== =======================================
``Range`` Traversal Category ``range_reference<Range>::type``
============================= ================== =======================================
``CAtlArray<E,ET>`` Random Access ``E&``
----------------------------- ------------------ ---------------------------------------
``CAutoPtrArray<E>`` Random Access ``E&``
----------------------------- ------------------ ---------------------------------------
``CInterfaceArray<I,pi>`` Random Access ``CComQIPtr<I,pi>&``
----------------------------- ------------------ ---------------------------------------
``CAtlList<E,ET>`` Bidirectional ``E&``
----------------------------- ------------------ ---------------------------------------
``CAutoPtrList<E>`` Bidirectional ``E&``
----------------------------- ------------------ ---------------------------------------
``CHeapPtrList<E,A>`` Bidirectional ``E&``
----------------------------- ------------------ ---------------------------------------
``CInterfaceList<I,pi>`` Bidirectional ``CComQIPtr<I,pi>&``
----------------------------- ------------------ ---------------------------------------
``CAtlMap<K,V,KT,VT>`` Forward ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CRBTree<K,V,KT,VT>`` Bidirectional ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CRBMap<K,V,KT,VT>`` Bidirectional ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CRBMultiMap<K,V,KT,VT>`` Bidirectional ``Range::CPair&``
----------------------------- ------------------ ---------------------------------------
``CSimpleStringT<B,b>`` Random Access ``B&``
----------------------------- ------------------ ---------------------------------------
``CStringT<B,ST>`` Random Access ``B&``
----------------------------- ------------------ ---------------------------------------
``CFixedStringT<S,n>`` Random Access ``range_reference<S>::type``
----------------------------- ------------------ ---------------------------------------
``CStringT<B,ST>`` Random Access ``B&``
----------------------------- ------------------ ---------------------------------------
``CComBSTR`` Random Access ``OLECHAR&``
----------------------------- ------------------ ---------------------------------------
``CSimpleArray<T,TE>`` Random Access ``T&``
============================= ================== =======================================
Other `Boost.Range`_ metafunctions are defined by the following.
Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
``range_value<Range>::type`` is the same as ``remove_reference<Ref>::type``,
``range_difference<Range>::type`` is the same as ``std::ptrdiff_t``, and
``range_pointer<Range>::type`` is the same as ``add_pointer<remove_reference<Ref>::type>::type``.
As for ``const Range``, see `const Ranges`_.
============
const Ranges
============
``range_reference<const Range>::type`` is defined by the following algorithm.
Let ``Range`` be any type listed above and ``ReF`` be the same as ``range_reference<Range>::type``.
.. parsed-literal::
if (Range is CObArray || Range is CObList)
return CObject const \* &
else if (Range is CPtrArray || Range is CPtrList)
return void const \* &
else if (there is a type X such that X& is the same as ReF)
return X const &
else if (there is a type X such that X* const is the same as ReF)
return X const \* const
else
return ReF
Other `Boost.Range`_ metafunctions are defined by the following.
``range_value<const Range>::type`` is the same as ``range_value<Range>::type``,
``range_difference<const Range>::type`` is the same as ``std::ptrdiff_t``, and
``range_pointer<const Range>::type`` is the same as ``add_pointer<remove_reference<range_reference<const Range>::type>::type>::type``.
==========
References
==========
- `Boost.Range`_
- `MFC Collections`__
- `ATL Collection Classes`__
__ http://msdn2.microsoft.com/en-us/library/942860sh.aspx
__ http://msdn2.microsoft.com/en-US/library/15e672bd.aspx
.. _Boost C++ Libraries: http://www.boost.org/
.. _Boost: `Boost C++ Libraries`_
.. _Boost.Range: ../index.html
.. _forward: range.html#forward_range
.. _bidirectional: range.html#forward_range
.. _random access: range.html#random_access_range

View File

@ -36,7 +36,7 @@ href="http://boost.sourceforge.net/regression-logs/developer/range.html">here</a
<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>
href="boost_range.html#range_iterator"><code >range_iterator</code></a>
and a single function definition instead of overloaded versions for const and
non-const arguments.
@ -75,7 +75,7 @@ href="http://boost.sourceforge.net/regression-logs/developer/range.html">here</a
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>

View File

@ -50,7 +50,7 @@
Range provides iterators for accessing a half-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.
<i>much</i> fewer requirements than a Container.
</p>
<p>
The motivation for the Range concept is
@ -78,9 +78,9 @@
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>
the range concepts are named to reflect which traversal category their
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/refmanual/metafunction.html">metafunctions</a> and all
@ -118,11 +118,7 @@ Single Pass Iterator</a>
<h3>Associated types</h3>
<table border="1" cellpadding="5">
<TR>
<TD VAlign="top">Value type</TD>
<TD VAlign="top"><code>boost::range_value&lt;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>boost::range_iterator&lt;X>::type</code></TD>
@ -132,7 +128,7 @@ Single Pass Iterator</a>
</TR>
<TR>
<TD VAlign="top">Const iterator type</TD>
<TD VAlign="top"><code>boost::range_const_iterator&lt;X>::type</code></TD>
<TD VAlign="top"><code>boost::range_iterator&lt;const 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>
@ -161,20 +157,16 @@ Single Pass Iterator</a>
<TD VAlign="top">Beginning of range</TD>
<TD VAlign="top"><code>boost::begin(a)</code></TD>
<TD VAlign="top"><code>boost::range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_iterator&lt;X>::type</code>
<code>a</code> is mutable, <code>boost::range_iterator&lt;const X>::type</code>
otherwise</TD> </TR>
<TR>
<TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>boost::end(a)</code></TD>
<TD VAlign="top"><code>boost::range_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_iterator&lt;X>::type</code>
<code>a</code> is mutable, <code>boost::range_iterator&lt;const X>::type</code>
otherwise</TD>
</TR>
<tr>
<TD VAlign="top">Is range empty?</TD>
<TD VAlign="top"><code>boost::empty(a)</code></TD>
<TD VAlign="top">Convertible to <code>bool</code></TD>
</TR>
</table>
<h3>Expression semantics</h3>
@ -188,7 +180,7 @@ otherwise</TD>
<TD VAlign="top"><code>boost::begin(a)</code></TD>
<TD VAlign="top">Returns an iterator pointing to the first element in the Range.</TD>
<TD VAlign="top"><code>boost::begin(a)</code> is either dereferenceable or past-the-end.
It is past-the-end if and only if <code>boost::size(a) == 0</code>.</TD>
It is past-the-end if and only if <code>boost::distance(a) == 0</code>.</TD>
</TR>
<TR>
<TD VAlign="top"><code>boost::end(a)</code></TD>
@ -196,19 +188,14 @@ otherwise</TD>
Range.</TD>
<TD VAlign="top"><code>boost::end(a)</code> is past-the-end.</TD>
</TR>
<TR>
<TD VAlign="top"><code>boost::empty(a)</code></TD>
<TD VAlign="top">Equivalent to <code>boost::begin(a) == boost::end(a)</code>. (But possibly
faster.)</TD>
<TD VAlign="top">&nbsp;-&nbsp;</TD>
</TR>
</table>
<h3>Complexity guarantees</h3>
All three functions are at most amortized linear time. For most practical
purposes, one can expect <code>boost::begin(a)</code>, <code>boost::end(a)</code> and <code>boost::empty(a)</code>
to be amortized constant time.
<code>boost::end(a)</code> is at most amortized linear time, <code>boost::begin(a)</code> is
amortized constant time. For most practical
purposes, one can expect both to be amortized constant time.
<h3>Invariants</h3>
<Table border>
@ -227,14 +214,17 @@ otherwise</TD>
<h3>See also</h3>
<p><a
href="boost_range.html#minimal_interface">Extending the library for UDTs </a></p>
<p> <a href="boost_range.html#boost::rang_difference">Implementation of
metafunctions </a></p>
<p> <a href="boost_range.html#begin">Implementation of
functions </a></p>
<p>
<A href="http://www.sgi.com/Technology/STL/Container.html">Container</A>
</p>
<p> <a href="boost_range.html#boost::range_value">implementation of
metafunctions </a></p>
<p> <a href="boost_range.html#begin">implementation of
functions </a></p>
<hr>
<a name=forward_range><h2>Forward Range</h2>
@ -261,76 +251,8 @@ href="../../iterator/doc/new-iter-concepts.html#forward-traversal-iterators-lib-
<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>boost::range_difference&lt;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>boost::range_size&lt;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>boost::size(a)</code></TD>
<TD VAlign="top"><code>boost::range_size&lt;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>boost::size(a)</code></TD>
<TD VAlign="top">Returns the size of the Range, that is, its number
of elements. Note <code>boost::size(a) == 0u</code> is equivalent to
<code>boost::empty(a).</code></TD>
<TD VAlign="top"><code>boost::size(a) &gt;= 0</TD>
</TR>
</table>
<h3>Complexity guarantees</h3>
<p><code>boost::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>boost::size(a)</code> is equal to the distance from <code>boost::begin(a)</code>
to <code>boost::end(a)</code>.</TD> </table>
</p>
<h3>See also</h3>
<p> <a href="boost_range.html#boost::range_difference">implementation of
metafunctions </a></p>
<p> <a href="boost_range.html#size">implementation of
functions </a></p>
<hr>
<a name="bidirectional_range"><h2>Bidirectional Range</h2>
@ -356,84 +278,9 @@ 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>boost::range_reverse_iterator&lt;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>boost::range_const_reverse_iterator&ltX>::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>boost::rbegin(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
<TD VAlign="top">Equivalent to
<code>boost::range_reverse_iterator&lt;X>::type(boost::end(a))</code>.</TD> </TR>
<TR>
<TD VAlign="top">End of range</TD>
<TD VAlign="top"><code>boost::rend(a)</code></TD>
<TD VAlign="top"><code>boost::range_reverse_iterator&lt;X>::type</code> if
<code>a</code> is mutable, <code>boost::range_const_reverse_iterator&lt;X>::type</code>
otherwise.</TD>
<TD VAlign="top">Equivalent to
<code>boost::range_reverse_iterator&lt;X>::type(boost::begin(a))</code>.</TD> </tr>
</table>
<h3>Complexity guarantees</h3>
<code>boost::rbegin(a)</code> has the same complexity as <code>boost::end(a)</code> and <code>boost::rend(a)</code>
has the same complexity as <code>boost::begin(a)</code> from <a
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>[boost::rbegin(a),boost::rend(a))</code>
is a valid range, that is, <code>boost::rend(a)</code> is reachable from <code>boost::rbegin(a)</code>
in a finite number of increments.</TD>
</TR>
<TR>
<TD VAlign="top">Completeness</TD>
<TD VAlign="top">An algorithm that iterates through the range <code>[boost::rbegin(a),boost::rend(a))</code>
will pass through every element of <code>a</code>.</TD>
</tr>
</table>
</p>
<h3>See also</h3>
<p> <a href="boost_range.html#boost::range_reverse_iterator">implementation of metafunctions </a></p>
<p> <a href="boost_range.html#rbegin">implementation of
functions </a></p>
<hr>
<a name=random_access_range><h2>Random Access Range</h2> <h3>Description</h3>
@ -455,7 +302,7 @@ href="../../iterator/doc/new-iter-concepts.html#random-access-traversal-iterator
<a name=concept_checking><h2>Concept Checking</h2>
Each of the range concepts has a corresponding concept checking
class in the file boost/range/concepts.hpp. These classes may be
class in the file <code><boost/range/concepts.hpp></codE>. These classes may be
used in conjunction with the <a
href="../../concept_check/concept_check.htm">Boost Concept
Check</a> library to insure that the type of a template parameter
@ -529,8 +376,8 @@ href="../../iterator/doc/new-iter-concepts.html#random-access-traversal-iterator
<TD><A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>
</TR>
<tr >
<TD nowrap>Copyright &copy 2004</TD>
<TD>Thorsten Ottosen. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
<TD nowrap>Copyright &copy 2004-2007</TD>
<TD>Thorsten Ottosen.
</TABLE>
<br>

View File

@ -1,10 +1,3 @@
/*
#// Copyright Thorsten Ottosen 2003-2005. 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)
*/
pre{
BORDER-RIGHT: gray 1pt solid;
PADDING-RIGHT: 2pt;

View File

@ -104,7 +104,7 @@
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>

View File

@ -59,19 +59,16 @@ corresponding <code>const_iterator</code> is. </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
Random Access 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>
incremented or anything. Likewise, if one creates a default constructed
<code>iterator_range</code>, then one have to be careful about not doing
anything besides copying. </p>
<h3>Synopsis</h3>
@ -82,11 +79,9 @@ corresponding <code>const_iterator</code> is. </p>
</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>typedef </span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>const_iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=identifier>iterator_difference</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>difference_type</span><span class=special>;</span>
</span><span class=keyword>public</span><span class=special>: </span><span class=comment>// construction, assignment
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator2 </span><span class=special>&gt;
@ -107,20 +102,22 @@ corresponding <code>const_iterator</code> is. </p>
</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=identifier>difference_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=special>( </span><span class=keyword>const</span> <span class=identifier>iterator_range</span><span class=special>& ) </span><span
class=keyword>const;</span>
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=identifier>front</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=identifier>back</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reference </span><span class=identifier>front</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reference </span><span class=identifier>back</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>iterator_range</span><span class=special>&amp;</span> <span class=identifier>advance_begin</span><span class=special>(</span> <span class=identifier>difference_type</span> <span class=identifier>n</span> <span class=special>);</span>
<span class=identifier>iterator_range</span><span class=special>&amp;</span> <span class=identifier>advance_end</span><span class=special>(</span> <span class=identifier>difference_type</span> <span class=identifier>n</span> <span class=special>);</span>
<span class=comment>// for Random Access Range only: </span>
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>size_type </span><span class=identifier>at </span><span class=special>) </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>reference </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>difference_type </span><span class=identifier>at </span><span class=special>) </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>value_type</span> <span class=keyword>operator</span><span class=special>()( </span><span class=identifier>difference_type </span><span class=identifier>at </span><span class=special>) </span><span class=keyword>const</span><span class=special>;</span>
</span><span class=special>};
</span><span class=comment>// stream output
@ -173,11 +170,11 @@ class=keyword>const;</span>
</span><span class=identifier>ForwardTraversalIterator </span><span class=identifier>End </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>const_iterator_of</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=identifier>make_iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>Range </span><span class=special>&gt;</span>
@ -187,7 +184,7 @@ class=keyword>const;</span>
</span><span class=keyword>typename </span><span class=identifier>range_difference</span><span class=special>&lt;</span><span class=identifier>Range</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>advance_end </span><span class=special>);
</span>
<span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>Range </span><span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>Range</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;</span>
<span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>Range</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;</span>
<span class=identifier>make_iterator_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>Range</span><span class=special>&amp; </span><span class=identifier>r</span><span class=special>,
</span><span class=keyword>typename </span><span class=identifier>range_difference</span><span class=special>&lt;</span><span class=identifier>Range</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>advance_begin</span><span class=special>,
</span><span class=keyword>typename </span><span class=identifier>range_difference</span><span class=special>&lt;</span><span class=identifier>Range</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>advance_end </span><span class=special>);</span>
@ -291,11 +288,13 @@ class can propagate constness since it knows what a corresponding
<span class=keyword>namespace </span><span class=identifier>boost</span>
<span class=special>{
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange </span><span class=special>&gt;
</span><span class=keyword>class </span><span class=identifier>sub_range </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_result_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=keyword>class </span><span class=identifier>sub_range </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>iterator_range</span><span class=special>&lt; </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=special>&gt;
</span><span class=special>{
</span><span class=keyword>public</span><span class=special>: </span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_result_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><spanclass=special>&gt;::</span><span class=identifier>type </span><span class=identifier>iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_const_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>const_iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=identifier>ForwardRange</span><spanclass=special>&gt;::</span><span class=identifier>type </span><span class=identifier>iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>range_iterator</span><span class=special>&lt;</span><span class=keyword>const </span><span class=identifier>ForwardRange</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>const_iterator</span><span class=special>;</span>
<span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>iterator_difference</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>difference_type</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>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardTraversalIterator </span><span class=special>&gt;
@ -305,7 +304,7 @@ class can propagate constness since it knows what a corresponding
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>Range2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=identifier>sub_range</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardRange2 </span><span class=special>&gt;
</span><span class=identifier>sub_range</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>=( </span><span class=identifier>ForwardRange2</span><span class=special>&amp; </span><span class=identifier>r </span><span class=special>);
@ -325,8 +324,8 @@ class can propagate constness since it knows what a corresponding
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=identifier>back</span><span class=special>();</span>
<span class=keyword>const </span><span class=identifier>value_type</span><span class=special>&amp; </span><span class=identifier>back</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span>
<span class=comment>// for Random Access Range only: </span>
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>size_type </span><span class=identifier>at </span><span class=special>);</span>
<span class=keyword>const </span><span class=identifier>value_type</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>size_type </span><span class=identifier>at </span><span class=special>) </span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>value_type</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>difference_type </span><span class=identifier>at </span><span class=special>);</span>
<span class=keyword>const </span><span class=identifier>value_type</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>[]( </span><span class=identifier>difference_type </span><span class=identifier>at </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 <a href=#iter_range><code>iterator_range</code></a>
@ -344,15 +343,15 @@ 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>&quot;hello&quot;</span><span class=special>);
</span><span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>&gt; </span><span class=identifier>ir </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>&quot;ll&quot; </span><span class=special>);
</span><span class=identifier>sub_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt; </span><span class=identifier>sub </span><span class=special>= </span><span class=identifier>find_first</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=string>&quot;ll&quot; </span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>str</span><span class=special>(</span><span class=string>&quot;hello&quot;</span><span class=special>);</span>
<span class=identifier>iterator_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>::</span><span class=identifier>iterator</span><span class=special>&gt;</span> <span class=identifier>ir</span> <span class=special>=</span> <span class=identifier>find_first</span><span class=special>(</span> <span class=identifier>str</span><span class=special>,</span> <span class=identifier>as_literal</span><span class=special>(</span><span class=string>&quot;ll&quot;</span><span class=special>)</span> <span class=special>);</span>
<span class=identifier>sub_range</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;</span> <span class=identifier>sub</span> <span class=special>=</span> <span class=identifier>find_first</span><span class=special>(</span> <span class=identifier>str</span><span class=special>,</span> <span class=identifier>as_literal</span><span class=special>(</span><span class=string>&quot;ll&quot;</span><span class=special>)</span> <span class=special>);</span>
</pre>
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004. Use, modification and distribution is subject to the Boost Software License, Version 1.0.
(C) Copyright Thorsten Ottosen 2003-2007
</p>
<br>

View File

@ -18,7 +18,7 @@
</table>
<p>
Copyright <20> 2003-2004 Thorsten Ottosen
Copyright <20> 2003-2007 Thorsten Ottosen
</p>
<p>
Use, modification and distribution is subject to the Boost Software License, Version 1.0
@ -52,16 +52,14 @@
<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/mfc_atl.html">MFC/ATL mapping (courtesy of Shunsuke
Sogame)</a></li>
<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>

1
test/TODO Normal file
View File

@ -0,0 +1 @@

View File

@ -17,6 +17,7 @@
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <algorithm>
@ -36,7 +37,7 @@ namespace
}
template< typename Range, typename T >
inline typename boost::range_const_iterator<Range>::type
inline typename boost::range_iterator<Range>::type
find( const Range& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
@ -46,7 +47,7 @@ namespace
// replace first value and return its index
//
template< class Range, class T >
inline typename boost::range_size<Range>::type
inline typename boost::range_difference<Range>::type
my_generic_replace( Range& c, const T& value, const T& replacement )
{
typename boost::range_iterator<Range>::type found = find( c, value );
@ -63,19 +64,15 @@ void check_algorithm()
//
// usage
//
const unsigned N = 5;
const int N = 5;
std::vector<int> my_vector;
int values[] = { 1,2,3,4,5,6,7,8,9 };
my_vector.assign( values, values + 9 );
typedef std::vector<int>::iterator iterator;
std::pair<iterator,iterator> my_view( boost::begin( my_vector ),
boost::begin( my_vector ) + N );
char str_val[] = "a string";
char* str = str_val;
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3u );
BOOST_CHECK_EQUAL( my_generic_replace( my_vector, 4, 2 ), 3 );
BOOST_CHECK_EQUAL( my_generic_replace( my_view, 4, 2 ), N );
BOOST_CHECK_EQUAL( my_generic_replace( str, 'a', 'b' ), 0u );
}

View File

@ -42,16 +42,16 @@ void check_array()
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_iterator<array_t>::type, int* >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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 ));
BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
BOOST_STATIC_ASSERT(( is_same< range_iterator<const array_t>::type, const int* >::value ));
#endif
BOOST_CHECK_EQUAL( begin( my_array ), my_array );
@ -62,6 +62,8 @@ void check_array()
BOOST_CHECK_EQUAL( end( ca ), ca + size( ca ) );
BOOST_CHECK_EQUAL( empty( ca ),false );
const char A[] = "\0A";
BOOST_CHECK_EQUAL( boost::size(A), 3 );
}
using boost::unit_test::test_suite;

623
test/atl.cpp Normal file
View File

@ -0,0 +1,623 @@
// Boost.Range ATL Extension
//
// Copyright Shunsuke Sogame 2005-2006.
// Distributed under 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)
// #include <pstade/vodka/drink.hpp>
#include <boost/test/test_tools.hpp>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define BOOST_LIB_NAME boost_test_exec_monitor
#include <boost/config/auto_link.hpp>
#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
#include <boost/range/atl.hpp> // can be placed first
#include <map>
#include <string>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/distance.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/foreach.hpp>
#include <atlbase.h> // for ATL3 CSimpleArray/CSimpleValArray
#if !(_ATL_VER < 0x0700)
#include <atlcoll.h>
#include <cstringt.h>
#include <atlsimpstr.h>
#include <atlstr.h>
#endif
namespace brdm = boost::range_detail_microsoft;
#if !(_ATL_VER < 0x0700)
template< class ArrayT, class SampleRange >
bool test_init_auto_ptr_array(ArrayT& arr, SampleRange& sample)
{
typedef typename boost::range_iterator<SampleRange>::type iter_t;
for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
arr.Add(*it); // moves ownership
}
return boost::distance(arr) == boost::distance(sample);
}
template< class ListT, class SampleRange >
bool test_init_auto_ptr_list(ListT& lst, SampleRange& sample)
{
typedef typename boost::range_iterator<SampleRange>::type iter_t;
typedef typename boost::range_value<SampleRange>::type val_t;
for (iter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
lst.AddTail(*it); // moves ownership
}
return boost::distance(lst) == boost::distance(sample);
}
// Workaround:
// CRBTree provides no easy access function, but yes, it is the range!
//
template< class AtlMapT, class KeyT, class MappedT >
bool test_atl_map_has(AtlMapT& map, const KeyT& k, const MappedT m)
{
typedef typename boost::range_iterator<AtlMapT>::type iter_t;
for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
if (it->m_key == k && it->m_value == m)
return true;
}
return false;
}
template< class AtlMapT, class MapT >
bool test_atl_map(AtlMapT& map, const MapT& sample)
{
typedef typename boost::range_iterator<AtlMapT>::type iter_t;
typedef typename boost::range_const_iterator<MapT>::type siter_t;
bool result = true;
result = result && (boost::distance(map) == boost::distance(sample));
if (!result)
return false;
{
for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->m_key, it->m_value));
}
}
{
for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
result = result && (test_atl_map_has)(map, it->first, it->second);
}
}
return result;
}
template< class MapT, class SampleMap >
bool test_init_atl_multimap(MapT& map, const SampleMap& sample)
{
typedef typename boost::range_const_iterator<SampleMap>::type iter_t;
for (iter_t it = boost::const_begin(sample), last = boost::const_end(sample); it != last; ++it) {
map.Insert(it->first, it->second);
}
return boost::distance(map) == boost::distance(sample);
}
// arrays
//
template< class Range >
void test_CAtlArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CAtlArray<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class ValT, class Range >
void test_CAutoPtrArray(Range& sample)
{
typedef ValT val_t;
typedef ATL::CAutoPtrArray<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> *> >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, boost::indirect_iterator< ATL::CAutoPtr<val_t> const*> >::value ));
rng_t rng;
BOOST_CHECK( ::test_init_auto_ptr_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class I, class Range >
void test_CInterfaceArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CInterfaceArray<I> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ATL::CComQIPtr<I> * >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ATL::CComQIPtr<I> const* >::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// lists
//
template< class Range >
void test_CAtlList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CAtlList<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class ValT, class Range >
void test_CAutoPtrList(Range& sample)
{
typedef ValT val_t;
typedef ATL::CAutoPtrList<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CAutoPtr<val_t> > > >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CAutoPtr<val_t> const> > >::value ));
rng_t rng;
BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class ValT, class Range >
void test_CHeapPtrList(const Range& sample)
{
typedef ValT val_t;
typedef ATL::CHeapPtrList<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t, ATL::CHeapPtr<val_t> > > >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, boost::indirect_iterator< brdm::list_iterator<rng_t const, ATL::CHeapPtr<val_t> const> > >::value ));
rng_t rng;
BOOST_CHECK( ::test_init_auto_ptr_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class I, class Range >
void test_CInterfaceList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CInterfaceList<I> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ATL::CComQIPtr<I> > >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ATL::CComQIPtr<I> const> >::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// strings
//
template< class Range >
void test_CSimpleStringT(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
ATL::CAtlStringA,
ATL::CAtlStringW
>::type derived_t;
typedef ATL::CSimpleStringT<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
derived_t drng;
rng_t& rng = drng;
BOOST_CHECK( brdm::test_init_string(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
// BOOST_CHECK( brdm::test_emptiness(rng) ); no default constructible
}
template< int n, class Range >
void test_CFixedStringT(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
ATL::CAtlStringA,
ATL::CAtlStringW
>::type base_t;
typedef ATL::CFixedStringT<base_t, n> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_string(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CStringT(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef typename boost::mpl::if_< boost::is_same<val_t, char>,
ATL::CAtlStringA, // == CStringT<char, X>
ATL::CAtlStringW // == CStringT<wchar_t, X>
>::type rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, typename rng_t::PXSTR>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, typename rng_t::PCXSTR>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_string(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CStaticString(const Range& sample)
{
#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
{
typedef ATL::CStaticString<char, 20> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, char const *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, char const *>::value ));
rng_t rng("hello static string");
BOOST_CHECK( *(boost::begin(rng)+4) == 'o' );
BOOST_CHECK( *(boost::end(rng)-3) == 'i' );
}
{
typedef ATL::CStaticString<wchar_t, 40> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, wchar_t const *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, wchar_t const *>::value ));
rng_t rng(L"hello static string");
BOOST_CHECK( *(boost::begin(rng)+4) == L'o' );
BOOST_CHECK( *(boost::end(rng)-3) == L'i' );
}
#endif
(void)sample; // unused
}
#endif // !(_ATL_VER < 0x0700)
template< class Range >
void test_CComBSTR(const Range& sample)
{
typedef ATL::CComBSTR rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, OLECHAR *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, OLECHAR const*>::value ));
rng_t rng(OLESTR("hello CComBSTR range!"));
BOOST_CHECK( brdm::test_equals(rng, std::string("hello CComBSTR range!")) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
(void)sample; // unused
}
// simples
//
template< class Range >
void test_CSimpleArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CSimpleArray<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CSimpleMap(const Range& sample)
{
#if !defined(BOOST_RANGE_ATL_NO_TEST_UNDOCUMENTED_RANGE)
typedef ATL::CSimpleMap<int, double> rng_t;
rng_t rng;
rng.Add(3, 3.0);
rng.Add(4, 2.0);
BOOST_CHECK( boost::begin(rng)->get<0>() == 3.0 );
BOOST_CHECK( (boost::end(rng)-1)->get<1>() == 2.0 );
#endif
(void)sample; // unused
}
template< class Range >
void test_CSimpleValArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ATL::CSimpleArray<val_t> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// maps
//
template< class MapT >
void test_CAtlMap(const MapT& sample)
{
typedef typename MapT::key_type k_t;
typedef typename MapT::mapped_type m_t;
typedef ATL::CAtlMap<k_t, m_t> rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_atl_map(rng, sample) );
}
template< class MapT >
void test_CRBTree(const MapT& sample)
{
typedef typename MapT::key_type k_t;
typedef typename MapT::mapped_type m_t;
typedef ATL::CRBMap<k_t, m_t> derived_t;
typedef ATL::CRBTree<k_t, m_t> rng_t;
derived_t drng;
rng_t& rng = drng;
boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(drng, sample) );
BOOST_CHECK( ::test_atl_map(rng, sample) );
}
template< class MapT >
void test_CRBMap(const MapT& sample)
{
typedef typename MapT::key_type k_t;
typedef typename MapT::mapped_type m_t;
typedef ATL::CRBMap<k_t, m_t> rng_t;
rng_t rng;
boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_atl_map(rng, sample) );
}
template< class MapT >
void test_CRBMultiMap(const MapT& sample)
{
typedef typename MapT::key_type k_t;
typedef typename MapT::mapped_type m_t;
typedef ATL::CRBMultiMap<k_t, m_t> rng_t;
rng_t rng;
boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
BOOST_CHECK( ::test_init_atl_multimap(rng, sample) );
BOOST_CHECK( ::test_atl_map(rng, sample) );
}
// main test
//
void test_atl()
{
// ordinary ranges
//
{
std::string sample("rebecca judy and mary whiteberry chat monchy");
#if !(_ATL_VER < 0x0700)
::test_CAtlArray(sample);
::test_CAtlList(sample);
::test_CSimpleStringT(sample);
::test_CFixedStringT<44>(sample);
::test_CStringT(sample);
::test_CStaticString(sample);
#endif
::test_CComBSTR(sample);
::test_CSimpleArray(sample);
::test_CSimpleMap(sample);
::test_CSimpleValArray(sample);
}
{
std::wstring sample(L"rebecca judy and mary whiteberry chat monchy");
#if !(_ATL_VER < 0x0700)
::test_CAtlArray(sample);
::test_CAtlList(sample);
::test_CSimpleStringT(sample);
::test_CFixedStringT<44>(sample);
::test_CStringT(sample);
::test_CStaticString(sample);
#endif
::test_CComBSTR(sample);
::test_CSimpleArray(sample);
::test_CSimpleMap(sample);
::test_CSimpleValArray(sample);
}
// pointer ranges
//
#if !(_ATL_VER < 0x0700)
{
typedef ATL::CAutoPtr<int> ptr_t;
ptr_t
ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
ptr_t ptrs[8] = {
ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
};
boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
::test_CAutoPtrArray<int>(workaround);
}
{
typedef ATL::CAutoPtr<int> ptr_t;
ptr_t
ptr0(new int(3)), ptr1(new int(4)), ptr2(new int(5)), ptr3(new int(4)),
ptr4(new int(1)), ptr5(new int(2)), ptr6(new int(4)), ptr7(new int(0));
ptr_t ptrs[8] = {
ptr0, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7
};
boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
::test_CAutoPtrList<int>(workaround);
}
{
typedef ATL::CHeapPtr<int> ptr_t;
ptr_t ptrs[5]; {
ptrs[0].AllocateBytes(sizeof(int));
ptrs[1].AllocateBytes(sizeof(int));
ptrs[2].AllocateBytes(sizeof(int));
ptrs[3].AllocateBytes(sizeof(int));
ptrs[4].AllocateBytes(sizeof(int));
}
boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+5);
::test_CHeapPtrList<int>(workaround);
}
{
typedef ATL::CComQIPtr<IDispatch> ptr_t;
ptr_t ptrs[8];
boost::iterator_range< ptr_t * > workaround(ptrs, ptrs+8);
::test_CInterfaceArray<IDispatch>(workaround);
::test_CInterfaceList<IDispatch>(workaround);
}
#endif
// maps
//
{
#if !(_ATL_VER < 0x0700)
std::map<int, std::string> sample; {
sample[0] = "hello";
sample[1] = "range";
sample[2] = "atl";
sample[3] = "mfc";
sample[4] = "collections";
}
::test_CAtlMap(sample);
::test_CRBTree(sample);
::test_CRBMap(sample);
::test_CRBMultiMap(sample);
#endif
}
} // test_atl
#include <boost/test/unit_test.hpp>
using boost::unit_test::test_suite;
test_suite *
init_unit_test_suite(int argc, char* argv[])
{
test_suite *test = BOOST_TEST_SUITE("ATL Range Test Suite");
test->add(BOOST_TEST_CASE(&test_atl));
(void)argc, (void)argv; // unused
return test;
}

0
test/compat1.cpp Executable file
View File

View File

@ -25,7 +25,7 @@
// Generic range algorithm
//
template< class Rng >
typename boost::range_result_iterator<Rng>::type foo_algo( Rng& r )
typename boost::range_iterator<Rng>::type foo_algo( Rng& r )
{
//
// This will only compile for Rng = UDT if the qualified calls
@ -44,7 +44,6 @@ namespace Foo
typedef std::vector<int> data_t;
typedef data_t::iterator iterator;
typedef data_t::const_iterator const_iterator;
typedef data_t::size_type size_type;
data_t vec;
@ -57,32 +56,28 @@ namespace Foo
// to be defined because X defines the proper set of
// nested types.
//
inline X::iterator boost_range_begin( X& x )
inline X::iterator range_begin( X& x )
{
return x.vec.begin();
}
inline X::const_iterator boost_range_begin( const X& x )
inline X::const_iterator range_begin( const X& x )
{
return x.vec.begin();
}
inline X::iterator boost_range_end( X& x )
inline X::iterator range_end( X& x )
{
return x.vec.end();
}
inline X::const_iterator boost_range_end( const X& x )
inline X::const_iterator range_end( const X& x )
{
return x.vec.end();
}
inline X::size_type boost_range_size( const X& x )
{
return x.vec.size();
}
}
void check_extension()

View File

@ -15,6 +15,7 @@
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range/concepts.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>
#include <boost/static_assert.hpp>
@ -46,33 +47,35 @@ void check_iterator_pair()
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_iterator<pair_t>::type, pair_t::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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 ));
//
// This behavior is not supported with v2.
//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_STATIC_ASSERT(( is_same< range_iterator<const_pair_tt>::type, const_pair_tt::first_type >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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( size( pair ) == 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( size( const_pair ) == 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 ) ) );
BOOST_CHECK( size( constness_pair ) == std::distance( constness_pair.first, constness_pair.second ) );
}

View File

@ -8,6 +8,7 @@
// For more information, see http://www.boost.org/libs/range/
//
//#include <boost/range/as_array.hpp>
#include <boost/detail/workaround.hpp>
@ -16,9 +17,9 @@
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range/iterator_range.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <iostream>
@ -66,6 +67,12 @@ void check_iterator_range()
distance( begin( r2 ), end( r2 ) ) );
cout << r << r2;
#ifndef BOOST_NO_STD_WSTRING
wcout << make_iterator_range( wstring( L"a wide string" ) )
<< make_iterator_range( L"another wide string" );
#endif
string res = copy_range<string>( r );
BOOST_CHECK( equal( res.begin(), res.end(), r.begin() ) );
@ -73,12 +80,12 @@ void check_iterator_range()
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 ) );
BOOST_CHECK( rr == as_literal("hello") );
BOOST_CHECK( rr != as_literal("hell") );
BOOST_CHECK( rr < as_literal("hello dude") );
BOOST_CHECK( as_literal("hello") == rr );
BOOST_CHECK( as_literal("hell") != rr );
BOOST_CHECK( ! (as_literal("hello dude") < rr ) );
irange rrr = rr;
BOOST_CHECK( rrr == rr );
BOOST_CHECK( !( rrr != rr ) );
@ -88,9 +95,10 @@ void check_iterator_range()
BOOST_CHECK_EQUAL( cr.front(), 'h' );
BOOST_CHECK_EQUAL( cr.back(), 'd' );
BOOST_CHECK_EQUAL( cr[1], 'e' );
BOOST_CHECK_EQUAL( cr(1), 'e' );
rrr = make_iterator_range( str, 1, -1 );
BOOST_CHECK( rrr == "ello worl" );
BOOST_CHECK( rrr == as_literal("ello worl") );
rrr = make_iterator_range( rrr, -1, 1 );
BOOST_CHECK( rrr == str );
@ -121,7 +129,7 @@ test_suite* init_unit_test_suite( int argc, char* argv[] )
template< class Container >
int test_iter_range( Container& a_cont )
{
typedef BOOST_DEDUCED_TYPENAME range_result_iterator<Container>::type citer_type;
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type citer_type;
typedef iterator_range<citer_type> riter_type;
riter_type a_riter( make_iterator_range( a_cont ) );
a_riter.front();

View File

@ -1,86 +1,743 @@
// Boost.Range library
// Boost.Range MFC Extension
//
// 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
// Copyright Shunsuke Sogame 2005-2006.
// Distributed under 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/
//
#define _MSL_USING_NAMESPACE 1
#include <boost/detail/workaround.hpp>
#include <afx.h> // must be here
#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
#define BOOST_RANGE_ENABLE_MFC
#define BOOST_RANGE_ENABLE_MCF_CARRAY
/*
#define WIN32
#define _WINDOWS
#define _MBCS
#define _AFXDLL
#define _ATL_DLL
*/
///Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_MBCS" /D "_AFXDLL" /D "_ATL_DLL" /Gm /EHsc /RTC1
// /MDd /Zc:wchar_t /Yu"stdafx.h" /Fp"Debug/Foo.pch" /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP
#include <boost/range.hpp>
#include <boost/range/detail/mfc/carray.hpp>
#include <boost/range/detail/mfc/cstring.hpp>
// #include <pstade/vodka/drink.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/config.hpp>
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define BOOST_LIB_NAME boost_test_exec_monitor
#include <boost/config/auto_link.hpp>
#define BOOST_RANGE_DETAIL_MICROSOFT_TEST
#include <boost/range/mfc.hpp> // can be placed first
void check_mfc()
#include <map>
#include <boost/concept_check.hpp>
// #include <boost/foreach.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/concepts.hpp>
#include <boost/range/end.hpp>
#include <boost/static_assert.hpp>
#include <boost/algorithm/string.hpp>
#include <afx.h>
#include <afxcoll.h>
#include <afxtempl.h>
#if !(_ATL_VER < 0x0700)
#include <cstringt.h>
#include <atlsimpstr.h>
#include <atlstr.h>
#endif
namespace brdm = boost::range_detail_microsoft;
// helpers
//
template< class MfcMapT, class MapT >
bool test_mfc_map(MfcMapT& map, const MapT& sample)
{
CString s = "hello world";
BOOST_CHECK( boost::begin( s ) + boost::size( s ) == boost::end( s ) );
BOOST_CHECK( boost::size( s ) == boost::size( "hello world" ) );
BOOST_CHECK( !boost::empty( s ) );
const CString cs( s );
BOOST_CHECK( boost::begin( cs ) + boost::size( cs ) == boost::end( cs ) );
BOOST_CHECK( boost::size( cs ) == boost::size( "hello world" ) );
BOOST_CHECK( !boost::empty( cs ) );
typedef typename boost::range_iterator<MfcMapT>::type iter_t;
typedef typename boost::range_const_iterator<MapT>::type siter_t;
CArray<int,int> a;
BOOST_CHECK( boost::empty( a ) );
a.Add( 5 );
a.Add( 10 );
BOOST_CHECK( boost::begin( a ) + boost::size( a ) == boost::end( a ) );
BOOST_CHECK( boost::size( a ) == 2 );
BOOST_CHECK( !boost::empty( a ) );
const CArray<int,int>& ca = a;
BOOST_CHECK( boost::begin( ca ) + boost::size( ca ) == boost::end( ca ) );
BOOST_CHECK( boost::size( ca ) == 2 );
BOOST_CHECK( !boost::empty( ca ) );
bool result = true;
result = result && (boost::distance(map) == boost::distance(sample));
if (!result)
return false;
{
for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
result = result && brdm::test_find_key_and_mapped(sample, *it);
}
}
{
for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
result = result && (map[it->first] == it->second);
}
}
return result;
}
template< class MfcMapT, class MapT >
bool test_mfc_cpair_map(MfcMapT& map, const MapT& sample)
{
typedef typename boost::range_iterator<MfcMapT>::type iter_t;
typedef typename boost::range_const_iterator<MapT>::type siter_t;
bool result = true;
result = result && (boost::distance(map) == boost::distance(sample));
if (!result)
return false;
{
for (iter_t it = boost::begin(map), last = boost::end(map); it != last; ++it) {
result = result && brdm::test_find_key_and_mapped(sample, std::make_pair(it->key, it->value));
}
}
{
for (siter_t it = boost::begin(sample), last = boost::end(sample); it != last; ++it) {
result = result && (map[it->first] == it->second);
}
}
return result;
}
// arrays
//
template< class Range >
void test_CByteArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CByteArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, BYTE *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, BYTE const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CDWordArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CDWordArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, DWORD *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, DWORD const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CObArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CObArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, ::CObject *> >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const ::CObject *> >::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CPtrArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CPtrArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, brdm::mfc_ptr_array_iterator<rng_t, void *> >::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, brdm::mfc_ptr_array_iterator<const rng_t, const void *> >::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CStringArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CStringArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, ::CString *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, ::CString const *>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CUIntArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CUIntArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, UINT *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, UINT const *>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CWordArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CWordArray rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, WORD *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, WORD const *>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// lists
//
template< class Range >
void test_CObList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CObList rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CObject *> >::value ));
#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const *> >::value ));
#else
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CObject const * const, ::CObject const * const> >::value ));
#endif
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CPtrList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CPtrList rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, void *> >::value ));
#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const *> >::value ));
#else
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, void const * const, void const * const> >::value ));
#endif
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CStringList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CStringList rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, ::CString> >::value ));
#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const> >::value ));
#else
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, ::CString const, ::CString const> >::value ));
#endif
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// maps
//
template< class MapT >
void test_CMapPtrToWord(const MapT& sample)
{
typedef ::CMapPtrToWord rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapPtrToPtr(const MapT& sample)
{
typedef ::CMapPtrToPtr rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapStringToOb(const MapT& sample)
{
typedef ::CMapStringToOb rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapStringToPtr(const MapT& sample)
{
typedef ::CMapStringToPtr rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapStringToString(const MapT& sample)
{
typedef ::CMapStringToString rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
#endif
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapWordToOb(const MapT& sample)
{
typedef ::CMapWordToOb rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMapWordToPtr(const MapT& sample)
{
typedef ::CMapWordToPtr rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
BOOST_CHECK( ::test_mfc_map(rng, sample) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// templates
//
template< class Range >
void test_CArray(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CArray<val_t, const val_t&> rng_t; // An old MFC needs the second template argument.
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, val_t *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, val_t const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_array(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class Range >
void test_CList(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CList<val_t, const val_t&> rng_t;
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter< rng_t, brdm::list_iterator<rng_t, val_t> >::value ));
#if !defined(BOOST_RANGE_MFC_CONST_COL_RETURNS_NON_REF)
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const> >::value ));
#else
BOOST_STATIC_ASSERT(( brdm::test_const_iter < rng_t, brdm::list_iterator<rng_t const, val_t const, val_t const> >::value ));
#endif
rng_t rng;
BOOST_CHECK( brdm::test_init_list(rng, sample) );
BOOST_CHECK( brdm::test_bidirectional(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
template< class MapT >
void test_CMap(const MapT& sample)
{
typedef typename MapT::key_type k_t;
typedef typename MapT::mapped_type m_t;
typedef ::CMap<k_t, const k_t&, m_t, const m_t&> rng_t;
rng_t rng;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
BOOST_CHECK( brdm::test_init_map(rng, sample) );
#if !defined(BOOST_RANGE_MFC_NO_CPAIR)
BOOST_CHECK( ::test_mfc_cpair_map(rng, sample) );
#endif
BOOST_CHECK( brdm::test_emptiness(rng) );
}
void test_CTypedPtrArray()
{
typedef ::CTypedPtrArray< ::CPtrArray, int * > rng_t;
boost::function_requires< boost::RandomAccessRangeConcept<rng_t> >();
rng_t rng;
int o1, o2, o3, o4, o5;
int *data[] = { &o1, &o2, &o3, &o4, &o5 };
BOOST_CHECK( brdm::test_init_array(rng, boost::make_iterator_range(data, data+5)) );
BOOST_CHECK( *(boost::begin(rng) + 2) == &o3 );
BOOST_CHECK( *(boost::end(rng) - 1) == &o5 );
// BOOST_CHECK( brdm::test_random_access(rng) ); this range is not mutable
BOOST_CHECK( brdm::test_emptiness(rng) );
}
void test_CTypedPtrList()
{
typedef ::CTypedPtrList< ::CObList, ::CObList * > rng_t;
boost::function_requires< boost::BidirectionalRangeConcept<rng_t> >();
rng_t rng;
::CObList o1, o2, o3, o4, o5;
::CObList *data[] = { &o1, &o2, &o3, &o4, &o5 };
BOOST_CHECK( brdm::test_init_list(rng, data) );
boost::range_iterator<rng_t>::type it = boost::begin(rng);
std::advance(it, 1);
BOOST_CHECK( *it == &o2 );
std::advance(it, 2);
BOOST_CHECK( *it == &o4 );
// BOOST_CHECK( brdm::test_bidirectional(rng) ); this range is not mutable
BOOST_CHECK( brdm::test_emptiness(rng) );
}
void test_CTypedPtrMap()
{
typedef ::CTypedPtrMap< ::CMapStringToPtr, ::CString, int *> rng_t;
boost::function_requires< boost::ForwardRangeConcept<rng_t> >();
rng_t rng;
::CString o0(_T('a')), o1(_T('c')), o2(_T('f')), o3(_T('q')), o4(_T('g'));
int d0, d1, d2, d3, d4;
std::map< ::CString, int * > data;
data[o0] = &d0, data[o1] = &d1, data[o2] = &d2, data[o3] = &d3, data[o4] = &d4;
BOOST_CHECK( brdm::test_init_map(rng, data) );
BOOST_CHECK( ::test_mfc_map(rng, data) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
// strings
//
#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
template< class Range >
void test_CString(const Range& sample)
{
typedef typename boost::range_value<Range>::type val_t;
typedef ::CString rng_t; // An old MFC needs the second template argument.
BOOST_STATIC_ASSERT(( brdm::test_mutable_iter<rng_t, TCHAR *>::value ));
BOOST_STATIC_ASSERT(( brdm::test_const_iter <rng_t, TCHAR const*>::value ));
rng_t rng;
BOOST_CHECK( brdm::test_init_string(rng, sample) );
BOOST_CHECK( brdm::test_random_access(rng) );
BOOST_CHECK( brdm::test_emptiness(rng) );
}
#endif
struct CPerson
{
void hello_range() { };
};
void test_mfc()
{
#if 0
// overview
//
{
CTypedPtrArray<CPtrArray, CList<CString> *> myArray;
// ...
BOOST_FOREACH (CList<CString> *theList, myArray)
{
BOOST_FOREACH (CString& str, *theList)
{
boost::to_upper(str);
std::sort(boost::begin(str), boost::end(str));
// ...
}
}
}
#endif
// arrays
//
{
BYTE data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
::test_CByteArray(boost::make_iterator_range(data, data+22));
}
{
DWORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
test_CDWordArray(boost::make_iterator_range(data, data+22));
}
{
::CObArray o1, o2, o3, o4, o5;
::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
::test_CObArray(boost::make_iterator_range(data, data+5));
}
{
::CPtrArray o1, o2, o3, o4, o5;
void *data[] = { &o1, &o2, &o3, &o4, &o5 };
::test_CPtrArray(boost::make_iterator_range(data, data+5));
}
{
::CString data[] = {
::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
};
::test_CStringArray(boost::make_iterator_range(data, data+8));
}
{
::CUIntArray rng;
UINT data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
::test_CUIntArray(boost::make_iterator_range(data, data+22));
}
{
::CWordArray rng;
WORD data[] = { 4,5,1,3,5,12,3,1,3,1,6,1,3,60,1,1,5,1,3,1,10 };
::test_CWordArray(boost::make_iterator_range(data, data+22));
}
// lists
//
{
::CObList rng;
::CObList o1, o2, o3, o4, o5;
::CObject *data[] = { &o1, &o2, &o3, &o4, &o5 };
::test_CObList(boost::make_iterator_range(data, data+5));
}
{
::CPtrList rng;
::CPtrList o1, o2, o3, o4, o5;
void *data[] = { &o1, &o2, &o3, &o4, &o5 };
::test_CPtrList(boost::make_iterator_range(data, data+5));
}
{
::CString data[] = {
::CString(_T('0')), ::CString(_T('1')), ::CString(_T('2')), ::CString(_T('3')),
::CString(_T('4')), ::CString(_T('5')), ::CString(_T('6')), ::CString(_T('7'))
};
::test_CStringList(boost::make_iterator_range(data, data+8));
}
// maps
//
{
std::map<void *, WORD> data;
int o0, o1, o2, o3, o4;
data[&o0] = 15, data[&o1] = 14, data[&o2] = 3, data[&o3] = 6, data[&o4] = 1;
::test_CMapPtrToWord(data);
}
{
std::map<void *, void*> data;
int o0, o1, o2, o3, o4;
data[&o0] = &o3, data[&o1] = &o2, data[&o2] = &o1, data[&o3] = &o0, data[&o4] = &o4;
::test_CMapPtrToPtr(data);
}
{
std::map< ::CString, CObject * > data;
CObArray o0, o1, o2, o3, o4;
data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
::test_CMapStringToOb(data);
}
{
std::map< ::CString, void * > data;
CObArray o0, o1, o2, o3, o4;
data[ ::CString('0') ] = &o0, data[ ::CString('1') ] = &o1, data[ ::CString('2') ] = &o2,
data[ ::CString('3') ] = &o3, data[ ::CString('4') ] = &o4;
::test_CMapStringToPtr(data);
}
{
std::map< ::CString, ::CString > data;
CString o0('a'), o1('b'), o2('c'), o3('d'), o4('e');
data[ ::CString('0') ] = o0, data[ ::CString('1') ] = o1, data[ ::CString('2') ] = o2,
data[ ::CString('3') ] = o3, data[ ::CString('4') ] = o4;
::test_CMapStringToString(data);
}
{
std::map< WORD, CObject * > data;
::CDWordArray o0, o1, o2, o3, o4;
data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
::test_CMapWordToOb(data);
}
{
std::map< WORD, void * > data;
::CDWordArray o0, o1, o2, o3, o4;
data[21] = &o3, data[52] = &o2, data[12] = &o1, data[76] = &o0, data[54] = &o4;
::test_CMapWordToPtr(data);
}
// templates
//
{
std::string data("0987654321qwertyuiop");
::test_CArray(data);
::test_CList(data);
}
{
std::wstring data(L"asdfghjklzxcvbnm");
::test_CArray(data);
::test_CList(data);
}
{
std::map< int, std::string > data;
data[0] = "abcde", data[1] = "ajfie", data[2] = "lij", data[3] = "abc", data[4] = "ioiu";
::test_CMap(data);
}
// typed
//
{
::test_CTypedPtrArray();
::test_CTypedPtrList();
::test_CTypedPtrMap();
}
// strings
//
#if defined(BOOST_RANGE_MFC_HAS_LEGACY_STRING)
{
std::string data("123456789 abcdefghijklmn");
::test_CString(data);
}
#endif
} // test_mfc
#include <boost/test/unit_test.hpp>
using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
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_mfc ) );
test_suite *test = BOOST_TEST_SUITE("MFC Range Test Suite");
test->add(BOOST_TEST_CASE(&test_mfc));
(void)argc, (void)argv; // unused
return test;
}

View File

@ -17,18 +17,15 @@
#endif
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
//#define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 1
#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/functions.hpp>
#include <boost/range/detail/sfinae.hpp>
#include <boost/static_assert.hpp>

View File

@ -23,6 +23,7 @@
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <vector>
#include <algorithm>
@ -31,7 +32,7 @@ using namespace std;
void check_iterator()
{
typedef vector<char> vec_t;
typedef vector<int> vec_t;
typedef vec_t::iterator iterator;
typedef pair<iterator,iterator> pair_t;
typedef range_reverse_iterator<pair_t>::type rev_iterator;
@ -40,15 +41,8 @@ void check_iterator()
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";
int a[] = {1,2,3,4,5,6,7,8,9,10};
const int ca[] = {1,2,3,4,5,6,7,8,9,10,11,12};
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 ) ) );
@ -58,33 +52,16 @@ void check_iterator()
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/unit_test.hpp>
using boost::unit_test::test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );

View File

@ -35,27 +35,25 @@ void check_std_container()
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_iterator<const 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_iterator<vec_t>::type, vec_t::iterator >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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( (std::size_t)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() );
BOOST_CHECK( (std::size_t)size( cvec ) == cvec.size() );
}

View File

@ -17,7 +17,10 @@
# pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif
#include <boost/range.hpp>
#include <boost/range/as_array.hpp>
#include <boost/range/as_literal.hpp>
#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>
@ -26,36 +29,66 @@
#include <fstream>
#include <algorithm>
template< class T >
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
str_begin( T& r )
{
return boost::begin( boost::as_literal(r) );
}
template< class T >
inline BOOST_DEDUCED_TYPENAME boost::range_iterator<T>::type
str_end( T& r )
{
return boost::end( boost::as_literal(r) );
}
template< class T >
inline BOOST_DEDUCED_TYPENAME boost::range_size<T>::type
str_size( const T& r )
{
return boost::size( boost::as_literal(r) );
}
template< class T >
inline bool
str_empty( T& r )
{
return boost::empty( boost::as_literal(r) );
}
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 );
return std::find( str_begin(c), str_end(c),
value );
}
template< typename Container, typename T >
BOOST_DEDUCED_TYPENAME boost::range_const_iterator<Container>::type
BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
find( const Container& c, T value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
return std::find( str_begin(c), str_end(c),
value );
}
template< typename Container, typename T >
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
find_mutable( Container& c, T value )
{
boost::size( c );
boost::end( c );
return std::find( boost::begin( c ), boost::end( c ), value );
str_size( c );
return std::find( str_begin(c), str_end(c),
value );
}
template< typename Container, typename T >
BOOST_DEDUCED_TYPENAME boost::range_const_iterator<Container>::type
BOOST_DEDUCED_TYPENAME boost::range_iterator<const Container>::type
find_const( const Container& c, T value )
{
boost::size( c );
boost::end( c );
return std::find( boost::begin( c ), boost::end( c ), value );
str_size( c );
return std::find( str_begin(c), str_end(c),
value );
}
@ -74,60 +107,64 @@ void check_char()
typedef char char_array_t[10];
const char* char_s = "a string";
char my_string[] = "another string";
const char my_const_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_iterator<char_iterator_t>::type, char_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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_iterator<const 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_STATIC_ASSERT(( is_same< range_iterator<char_array_t>::type, char* >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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( str_begin( char_s ), char_s );
std::size_t sz = str_size(char_s);
const char* str_end1 = str_begin( char_s ) + sz;
BOOST_CHECK_EQUAL( str_end( char_s ), str_end1 );
BOOST_CHECK_EQUAL( str_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 );
BOOST_CHECK_EQUAL( str_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 );
const char* str_end12 = str_begin( char_s2 ) + sz;
BOOST_CHECK_EQUAL( str_end( char_s2 ), str_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 ) );
BOOST_CHECK_EQUAL( str_begin( my_string ), my_string );
range_iterator<char_array_t>::type str_end2 = str_begin( my_string ) + str_size(my_string);
range_iterator<char_array_t>::type str_end3 = str_end(my_string);
BOOST_CHECK_EQUAL( str_end3, str_end2 );
BOOST_CHECK_EQUAL( str_empty( my_string ), (my_string == 0 || my_string[0] == char()) );
BOOST_CHECK_EQUAL( str_size( my_string ), my_string_length );
BOOST_CHECK_EQUAL( str_size( my_string ), std::char_traits<char>::length( my_string ) );
char to_search = 'n';
BOOST_CHECK( find_mutable( char_s, to_search ) != end( char_s ) );
BOOST_CHECK( find_const( char_s, to_search ) != end( char_s ) );
BOOST_CHECK( find_mutable( char_s, to_search ) != str_end( char_s ) );
BOOST_CHECK( find_const( char_s, to_search ) != str_end(char_s) );
BOOST_CHECK( find_mutable( my_string, to_search ) != end( my_string ) );
BOOST_CHECK( find_const( my_string, to_search ) != end( my_string ) );
BOOST_CHECK( find_mutable( my_string, to_search ) != str_end(my_string) );
BOOST_CHECK( find_const( my_string, to_search ) != str_end(my_string) );
BOOST_CHECK( find_mutable( char_s2, to_search ) != end( char_s2 ) );
BOOST_CHECK( find_const( char_s2, to_search ) != end( char_s2 ) );
BOOST_CHECK( find_mutable( char_s2, to_search ) != str_end(char_s) );
BOOST_CHECK( find_const( char_s2, to_search ) != str_end(char_s2) );
BOOST_CHECK( find_const( as_array( my_string ), to_search ) != str_end(my_string) );
BOOST_CHECK( find_const( as_array( my_const_string ), to_search ) != str_end(my_string) );
}
@ -148,31 +185,31 @@ void check_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_iterator<const wchar_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 ));
BOOST_STATIC_ASSERT(( is_same< range_iterator<wchar_iterator_t>::type, wchar_iterator_t >::value ));
BOOST_STATIC_ASSERT(( is_same< range_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()) );
std::size_t sz = str_size( char_ws );
BOOST_CHECK_EQUAL( str_begin( char_ws ), char_ws );
BOOST_CHECK_EQUAL( str_end(char_ws), (str_begin( char_ws ) + sz) );
BOOST_CHECK_EQUAL( str_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( str_begin( char_ws2 ), char_ws2 );
BOOST_CHECK_EQUAL( str_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 ) );
BOOST_CHECK( find( char_ws, to_search ) != str_end(char_ws) );
#if BOOST_WORKAROUND(_MSC_VER, BOOST_TESTED_AT(1300))
BOOST_CHECK( find( my_wstring, to_search ) != end( my_wstring ) );
BOOST_CHECK( find( my_wstring, to_search ) != str_end(my_wstring) );
#endif
#endif
@ -181,7 +218,6 @@ void check_string()
}
#include <boost/test/unit_test.hpp>
using boost::unit_test::test_suite;

View File

@ -17,6 +17,7 @@
#endif
#include <boost/range/sub_range.hpp>
#include <boost/range/as_literal.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <string>
@ -91,16 +92,31 @@ void check_sub_range()
r.size();
s.size();
//
// As of range v2 not legal anymore.
//
//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 ) );
BOOST_CHECK( rr == as_literal("hello") );
BOOST_CHECK( rr != as_literal("hell") );
BOOST_CHECK( rr < as_literal("hello dude") );
BOOST_CHECK( as_literal("hello") == rr );
BOOST_CHECK( as_literal("hell") != rr );
BOOST_CHECK( ! (as_literal("hello dude") < rr ) );
irange rrr = rr;
BOOST_CHECK( rrr == rr );
@ -111,15 +127,16 @@ void check_sub_range()
BOOST_CHECK_EQUAL( cr.front(), 'h' );
BOOST_CHECK_EQUAL( cr.back(), 'd' );
BOOST_CHECK_EQUAL( cr[1], 'e' );
BOOST_CHECK_EQUAL( cr(1), 'e' );
rrr = make_iterator_range( str, 1, -1 );
BOOST_CHECK( rrr == "ello worl" );
BOOST_CHECK( rrr == as_literal("ello worl") );
rrr = make_iterator_range( rrr, -1, 1 );
BOOST_CHECK( rrr == str );
rrr.front() = 'H';
rrr.back() = 'D';
rrr[1] = 'E';
BOOST_CHECK( rrr == "HEllo worlD" );
BOOST_CHECK( rrr == as_literal("HEllo worlD") );
}
#include <boost/test/unit_test.hpp>