*** empty log message ***

[SVN r24371]
This commit is contained in:
Thorsten Jørgen Ottosen
2004-08-10 11:53:33 +00:00
parent 6157440017
commit e245cc6a7e
3 changed files with 395 additions and 310 deletions

View File

@ -8,8 +8,6 @@
<body> <body>
<table > <table >
<tr > <tr >
<td ><img src="cboost.gif" width="100%" border="0"></td> <td ><img src="cboost.gif" width="100%" border="0"></td>
@ -18,7 +16,7 @@
</tr> </tr>
</table> </table>
<h2>Range and ReversibleRange Implementation</h2> <h2>Single Pass Range, Forward Range and Bidirectional Range Implementation</h2>
<ul > <ul >
<li> <li>
@ -29,15 +27,12 @@
<li > <li >
<a href="#Semantics" >Semantics</a> <a href="#Semantics" >Semantics</a>
</li> </li>
<li >
<a href="#Examples" >Examples</a>
</li>
</ul> </ul>
<hr size="1" > <hr size="1" >
<h3>Overview</h3> <h3>Overview</h3>
<p> <p>
Five types of objects are currently supported by the library: Four types of objects are currently supported by the library:
<ul > <ul >
<li > <li >
standard containers standard containers
@ -53,21 +48,20 @@ Five types of objects are currently supported by the library:
built-in arrays built-in arrays
</li> </li>
</ul> </ul>
It is worth noticing that some functionality requires partial template
specialization, in particular, full array support does (remark: this is a very Even though the behavior of the primary templates are exactly such
small problem since one would use <code>boost::array<></code> anyway). Also note that standard containers will be supported by default, the requirements
that arrays and pointers of <code >char</code> or <code >whar_t</code> are are much lower than the standard container requirements. For example,
treated special because of their use in string algorithms. the utility class <a href="utility_class#iterator_range"><code>iterator_range</code></a> implements the minimal interface required to make the class
a <a href="range.htm#forward_range">Forward Range</a>.
</p> </p>
<p> <p>
The concept is defined by the metafunction and the functions below. Even Please also see <a href="range.htm">Range concepts</a> for more details.
though these functions are defined in namespace <code>boost</code>, there is no
such general requirement, that is, if one wants to extend the list of supported
types, it can be done in any namespace.
</p> </p>
<h3 >Synopsis</h3><a name="Synopsis" ></a> <a name="Synopsis" ></a>
<h3 >Synopsis</h3>
<p > <p >
@ -75,102 +69,150 @@ types, it can be done in any namespace.
namespace boost namespace boost
{ {
// //
// Range metafunctions // Single Pass Range metafunctions
// //
template< class T > template< class T >
struct <a href="#value_type_of" >value_type_of</a> struct <a href="#value_type_of" >value_type_of</a>;
{
typedef ... type; // type of stored objTts
};
template< class T > template< class T >
struct <a href="#iterator_of" >iterator_of</a> struct <a href="#iterator_of" >iterator_of</a>;
{
typedef ... type; // iterator over stored objects
};
template< class T > template< class T >
struct <a href="#const_iterator_of" >const_iterator_of</a> struct <a href="#const_iterator_of" >const_iterator_of</a>;
{
typedef ... type; // iterator over immutable stored objects
};
template< class T >
struct <a href="#difference_type_of" >difference_type_of</a>
{
typedef ... type;
BOOST_STATIC_ASSERT( boost::is_signed< type >::value );
//
// remark: if std::iterator_traits<> works for the type, this assertion must
hold
//
BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename
<a href="#iterator_of" >iterator_of</a>< T >::type >::difference_type>::value );
};
template< class T >
struct <a href="#size_type_of" >size_type_of</a>
{
typedef ... type;
BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value );
BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( <a href="#difference_type_of" >
difference_type_of</a>< T >::type ) );
};
template< class T >
struct <a href="#result_iterator_of" >result_iterator_of</a>
{
typedef ... type;
// <a href="#iterator_of" >iterator_of</a>< T >::type if T is non-const, <a href="#const_iterator_of" >
const_iterator_of</a>< T >::type otherwise
};
// //
// funtions // Forward Range metafunctions
// //
template< class T > template< class T >
inline typename iterator_of<T>::type struct <a href="#difference_type_of" >difference_type_of</a>;
template< class T >
struct <a href="#size_type_of" >size_type_of</a>;
//
// Bidirectional Range metafunctions
//
template< class T >
struct <a href="#reverse_iterator_of" >reverse_iterator_of</a>;
template< class T >
struct <a href="#const_reverse_iterator_of" >const_reverse_iterator_of</a>;
//
// Special metafunctions
//
template< class T >
struct <a href="#result_iterator_of" >result_iterator_of</a>;
template< class T >
struct <a href="#reverse_result_iterator_of" >reverse_result_iterator_of</a>;
//
// Single Pass Range functions
//
template< class T >
inline typename iterator_of&lt;T>::type
<a href="#begin" >begin</a>( T& c ); <a href="#begin" >begin</a>( T& c );
template< class T > template< class T >
inline typename const_iterator_of< T >::type inline typename const_iterator_of&lt;T>::type
<a href="#begin" >begin</a>( const T& c ); <a href="#begin" >begin</a>( const T& c );
template< class T > template< class T >
inline typename iterator_of< T >::type inline typename iterator_of&lt;T>::type
<a href="#end" >end</a>( T& c ); <a href="#end" >end</a>( T& c );
template< class T > template< class T >
inline typename const_iterator_of< T >::type inline typename const_iterator_of&lt;T>::type
<a href="#end" >end</a>( const T& c ); <a href="#end" >end</a>( const T& c );
template< class T > template< class T >
inline bool inline bool
<a href="#empty" >empty</a>( const T& c ); <a href="#empty" >empty</a>( const T& c );
//
// Forward Range functions
//
template< class T > template< class T >
inline typename size_type_of< T >::type inline typename size_type_of&lt;T>::type
<a href="#size" >size</a>( const T& c ); <a href="#size" >size</a>( const T& c );
//
// Bidirectional Range functions
//
template< class T >
inline typename reverse_iterator_of&lt;T>::type
<a href="#rbegin" >rbegin</a>( T& c );
template< class T >
inline typename const_reverse_iterator_of&lt;T>::type
<a href="#rbegin" >rbegin</a>( const T& c );
template< class T >
inline typename reverse_iterator_of&lt;T>::type
<a href="#rend" >rend</a>( T& c );
template< class T >
inline typename const_reverse_iterator_of&lt;T>::type
<a href="#rend" >rend</a>( const T& c );
} // namespace 'boost' </pre> } // namespace 'boost' </pre>
</p> </p>
<a name="Semantics" ></a>
<h3 >Semantics</h3>
<h3 >Semantics</h3><a name="Semantics" ></a> <h4>notation</h4>
<p> <p>
In the table <code >C</code> is a type that conforms to the <table cellpadding="5" border="1">
ExternalCollectionConcept and <code >c</code> is an object of that type.<code > <tr>
SC</code> <th>Type
will denote a standard container, <code >T[sz]</code> will denote an array of <th>Object
type <code >T</code> of size <code >sz</code>, <code >P</code> will denote <code > <th>Describes
std::pair&lt;&gt;</code>, </tr>
<code >I</code> means an iterator which default construction denotes the end of <tr>
the range and <code >sc,t,p,i</code> are objects of these types, respectively. <td><code>X</code>
Special cases for <code >char*</code> and <code >wchar_t*</code> are described <td> <code>x</code>
explicitly. <td>any type
</tr>
<tr>
<td><code>T</code> </td>
<td><code>t</code>
<td>denotes behavior of the primary templates</td>
</tr>
<tr>
<td><code>P</code>
<td><code>p</code>
<td>denotes <code>std::pair&lt;iterator,iterator></code>
</tr>
<tr>
<td><code>A[sz]</code>
<td><code>a</code>
<td>denotes an array of type <code>A</code> of size <code>sz</code>
<tr>
<tr>
<td><code>Char*</code>
<td><code>s</code>
<td>denotes either <code>char*</code> or <code>wchar_t*</code>
</tr>
</table>
</p> </p>
<p>
Please notice in tables below that when four lines appear in a
cell, the first line will describe the primary template, the second
line pairs of iterators, the third line arrays and the last line
null-terminated strings.
</p>
<h4>Metafunctions</h4>
<p>
<table border="1" cellpadding="5" > <table border="1" cellpadding="5" >
<tr > <tr >
<th >Expression</th> <th >Expression</th>
@ -179,75 +221,92 @@ explicitly.
</tr> </tr>
<tr > <tr >
<a name="value_type_of" ></a> <a name="value_type_of" ></a>
<td ><code >value_type_of&lt;C&gt;::type</code></td> <td ><code >value_type_of&lt;X&gt;::type</code></td>
<td ><code >SC::value_type</code><br> <td ><code >T::value_type</code><br>
<code >T</code><br> <code >boost::iterator_value&lt;P::first_type&gt;::type</code><br>
<code >std::iterator_traits&lt;P::first_type&gt;::value_type</code><br> <code >A</code><br>
<code>Char</code>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="iterator_of" ></a> <a name="iterator_of" ></a>
<td ><code >iterator_of&lt;C&gt;::type</code></td> <td ><code >iterator_of&lt;X&gt;::type</code></td>
<td ><code >SC::iterator</code><br> <td ><code >T::iterator</code><br>
<code >T*</code><br>
<code >P::first_type</code><br> <code >P::first_type</code><br>
<code >A*</code><br>
<code>Char*</code>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="const_iterator_of" ></a> <a name="const_iterator_of" ></a>
<td ><code >const_iterator_of&lt;C&gt;::type</code></td> <td ><code >const_iterator_of&lt;X&gt;::type</code></td>
<td ><code >SC::const_iterator</code><br> <td ><code >T::const_iterator</code><br>
<code >const T*</code><br>
<code >P::first_type</code><br> <code >P::first_type</code><br>
<code >const A*</code><br>
<code>const Char*</code>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="difference_type_of" ></a> <a name="difference_type_of" ></a>
<td ><code >difference_type_of&lt;C&gt;::type</code></td> <td ><code >difference_type_of&lt;X&gt;::type</code></td>
<td ><code >SC::difference_type</code><br> <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> <code >std::ptrdiff_t</code><br>
<code >std::iterator_traits&lt;P::first_type&gt;:: difference_type</code><br>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="size_type_of" ></a> <a name="size_type_of" ></a>
<td ><code >size_type_of&lt;C&gt;::type</code></td> <td ><code >size_type_of&lt;X&gt;::type</code></td>
<td ><code >SC::size_type</code><br> <td ><code >T::size_type</code><br>
<code >std::size_t</code><br>
<code >std::size_t</code><br> <code >std::size_t</code><br>
<code >std::size_t</code><br> <code >std::size_t</code><br>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="result_iterator_of" ></a> <a name="result_iterator_of" ></a>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td> <td ><code >result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >const_iterator_of&lt; C&gt;::type</code> if <code >C</code> is <code > <td ><code >const_iterator_of&lt;X&gt;::type</code> if <code
const</code> >X</code> is <code >const</code> <br>
<br> <code >iterator_of&lt;X&gt;::type</code> otherwise </td>
<code >iterator_of&lt;C&gt;::type</code> otherwise </td>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="reverse_iterator_of" ></a> <a name="reverse_iterator_of" ></a>
<td ><code >reverse_iterator_of&lt;C&gt;::type</code></td> <td ><code >reverse_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename iterator_of&lt;T>::type <td ><code >boost::reverse_iterator< typename iterator_of&lt;T>::type ></code><br>
></code><br> <td >compile time</td> <td >compile time</td>
</tr> </tr>
<tr > <tr >
<a name="const_reverse_iterator_of" ></a> <a name="const_reverse_iterator_of" ></a>
<td ><code >const_reverse_iterator_of&lt;C&gt;::type</code></td> <td ><code >const_reverse_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename const_iterator_of&lt;T>::type ></code><br> <td ><code >boost::reverse_iterator< typename const_iterator_of&lt;T>::type ></code>
<br>
<td >compile time</td> <td >compile time</td>
</tr> <tr > </tr>
<tr >
<a name="reverse_result_iterator_of" ></a> <a name="reverse_result_iterator_of" ></a>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td> <td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;:: <td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;::type ></code>
type ></code>
<td >compile time</td> <td >compile time</td>
</tr> </tr>
</table> </table>
<br> </p>
<p>
The special metafunctions <code>result_iterator_of</code> and
<code>reverse_result_iterator_of</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" > <table border="1" cellpadding="5" >
<tr > <tr >
<th >Expression</th> <th >Expression</th>
@ -257,103 +316,70 @@ explicitly.
</tr> </tr>
<tr > <tr >
<a name="begin" ></a> <a name="begin" ></a>
<td ><code >begin( c )</code></td> <td ><code >begin(x)</code></td>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td> <td ><code >result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >sc.begin()</code><br> <td ><code >t.begin()</code><br>
<code >t</code><br>
<code >p.first</code><br> <code >p.first</code><br>
<code >a</code><br>
<code>s</code>
<td >constant time</td> <td >constant time</td>
</tr> </tr>
<tr > <tr >
<a name="end" ></a> <a name="end" ></a>
<td ><code >end( c )</code></td> <td ><code >end(x)</code></td>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td> <td ><code >result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >sc.end()</code><br> <td ><code >t.end()</code><br>
<code >t + std::char_traits&lt;C&gt;::length( t )</code> if <code >C</code> is <code >
char*</code>
or <code >wchar_t*</code><br>
<code >t + sz - 1</code> if <code >C</code> is <code >char[sz]</code> or <code >
wchar_t[sz]</code>
<br>
<code >t + sz</code> otherwise <br>
<code >p.second</code><br> <code >p.second</code><br>
<td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code> <code >a + sz</code> <br>
<br> <code >s + std::char_traits&lt;X&gt;::length( s )</code> if
<code >X</code> is <code >Char*</code><br>
<code >s + sz - 1</code> if <code >X</code> is <code >Char[sz]</code> <br>
<td >linear if <code >X</code> is <code >Char*</code> <br>
constant time otherwise</td> constant time otherwise</td>
</tr> </tr>
<tr > <tr >
<a name="empty" ></a> <a name="empty" ></a>
<td ><code >empty( c )</code></td> <td ><code >empty(x)</code></td>
<td >Convertible to <code >bool</code></td> <td ><code >bool</code></td>
<td ><code >sc.empty()</code><br> <td ><code >begin(x) == end( x )</code><br>
<code >size( t ) == 0</code><br> <td >linear if <code >X</code> is <code >Char*</code> <br>
<code >p.first == p.second</code><br>
<td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code>
<br>
constant time otherwise<br> constant time otherwise<br>
</td> </td>
</tr> </tr>
<tr > <tr >
<a name="size" ></a> <a name="size" ></a>
<td ><code >size( c )</code></td> <td ><code >size(x)</code></td>
<td ><code >size_type_of&lt;C&gt;::type</code></td> <td ><code >size_type_of&lt;X&gt;::type</code></td>
<td ><code >sc.size()</code><br> <td ><code >t.size()</code><br>
<code >end( t ) - begin( t )</code><br> <code>std::distance(p.first,p.second)</code><br>
<code >distance( p. first, p.second )</code><br> <code >sz</code><br>
<td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code> <code>end(s) - s</code>
<br>
<td >linear if <code >X</code> is <code >Char*</code> <br>
or if <code >std::distance()</code> is linear <br> or if <code >std::distance()</code> is linear <br>
constant time otherwise</td> constant time otherwise</td>
</tr> </tr>
<tr > <tr >
<a name="rbegin" ></a> <a name="rbegin" ></a>
<td ><code >rbegin( c )</code></td> <td ><code >rbegin(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td> <td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type( end( c ) )</code> <td ><code >reverse_result_iterator_of&lt;X&gt;::type( end(x)
<br> )</code> <br> <td >same as <code>end(x)</code> </td>
<td >same as <code>end()</code> </td>
</tr> </tr>
<tr > <tr >
<a name="rend" ></a> <a name="rend" ></a>
<td ><code >rend( c )</code></td> <td ><code >rend(x)</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td> <td ><code >reverse_result_iterator_of&lt;X&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type( begin( c ) )</code> <td ><code >reverse_result_iterator_of&lt;X&gt;::type( begin(x)
<td > same as <code>begin()</code></td> )</code> <td >same as <code>begin(x)</code></td>
</tr> </tr>
</table> </table>
<p >
Please note that <code >char*</code>,<code >whar_t*</code>,<code >char[]</code>,
and <code >wchar_t[]</code> behaves differently from normal arrays only for <code >
size()</code>
and <code >end()</code>. Note that the null pointer is allowed as an argument
in these cases.
</p> </p>
<hr size="1" ><h2 >Examples</h2><a name="Examples" ></a>
<p >
Some examples are given in the accompanying test files:
</p>
<ul >
<li >
<a href="../test/iterator.cpp" target="_self" ><code >iterator.cpp</code></a>
</li>
shows how to implement a container version of <code >std::copy()</code> that
works with <code >std::ifstream_iterator&lt;&gt;.</code>
<li >
<a href="../test/string.cpp" target="_self" ><code >string.cpp</code></a>
</li>
shows how to implement a container version of <code >std::find()</code> that
works with <code >char[],wchar_t[],char*,wchar_t*.</code>
<li >
<a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a>
</li>
shows the replace example from the introduction.
</ul>
<hr> <hr>
<p> <p>
(C) Copyright Thorsten Ottosen 2003-2004 (C) Copyright Thorsten Ottosen 2003-2004

64
doc/examples.html Executable file
View File

@ -0,0 +1,64 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range Examples </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range </h1></td>
</tr>
</table>
<h2 >Examples</h2><a name="Examples" ></a>
<p >
Some examples are given in the accompanying test files:
</p>
<ul >
<li >
<a href="../test/string.cpp" target="_self" ><code >string.cpp</code></a>
</li>
shows how to implement a container version of <code >std::find()</code> that
works with <code >char[],wchar_t[],char*,wchar_t*.</code>
<li >
<a href="../test/algorithm_example.cpp" target="_self" ><code >algorithm_example.cpp</code></a>
</li>
shows the replace example from the introduction.
<li> <a href="../test/iterator_range.cpp">iterator_range.cpp</a>
<li> <a href="../test/sub_range.cpp">sub_range.cpp</a>
<li> <a href="../test/iterator_pair.cpp">iterator_pair.cpp</a>
<li> <a href="../test/reversible_range.cpp">reversible_range.cpp</a>
<li> <a href="../test/std_container.cpp">std_container.cpp</a>
<li> <a href="../test/array.cpp">array.cpp</a>
</ul>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

View File

@ -44,13 +44,7 @@
<li> <a href="doc/range.htm#random_access_range">RandomAccessRange</a> <li> <a href="doc/range.htm#random_access_range">RandomAccessRange</a>
</ul> </ul>
<li> <a href=doc/boost_range.html>Implementation</a> of Range concepts for <ul> <li> <a href=doc/boost_range.html>Implementation</a> of Range concepts
<li> standard containers
<li> null-terminated strings
<li> pairs of iterators
<li> arrays
</ul>
<li> <a href=doc/utility_class.html> Utilities:</a> <li> <a href=doc/utility_class.html> Utilities:</a>
<ul> <ul>
<li> Class <a href="doc/utility_class.html#iter_range"><code>iterator_range</code></a> <li> Class <a href="doc/utility_class.html#iter_range"><code>iterator_range</code></a>
@ -58,6 +52,7 @@
<li> <a href=doc/style.html>Terminology and style guidelines </a> <li> <a href=doc/style.html>Terminology and style guidelines </a>
<li><a href="doc/headers.html">Headers</a> </li> <li><a href="doc/headers.html">Headers</a> </li>
<li><a href="doc/examples.html">Examples</a>
<li><a href="doc/portability.html">Portability</a> <li><a href="doc/portability.html">Portability</a>
<li><a href="doc/faq.html">FAQ</a> <li><a href="doc/faq.html">FAQ</a>
<li><a href="doc/history_ack.html">History and acknowledgment</a> <li><a href="doc/history_ack.html">History and acknowledgment</a>