*** 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

@ -6,21 +6,19 @@
<link rel="stylesheet" href="style.css" type="text/css"> <link rel="stylesheet" href="style.css" type="text/css">
</head> </head>
<body> <body>
<table >
<table >
<tr > <tr >
<td ><img src="cboost.gif" width="100%" border="0"></td> <td ><img src="cboost.gif" width="100%" border="0"></td>
<td ><h1 ><br> <td ><h1 ><br>
Boost.Range </h1></td> Boost.Range </h1></td>
</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>
<a href="#overview">Overview</a> <a href="#overview">Overview</a>
<li > <li >
@ -29,16 +27,13 @@
<li > <li >
<a href="#Semantics" >Semantics</a> <a href="#Semantics" >Semantics</a>
</li> </li>
<li > </ul>
<a href="#Examples" >Examples</a> <hr size="1" >
</li>
</ul>
<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
</li> </li>
@ -52,126 +47,173 @@ Five types of objects are currently supported by the library:
<li > <li >
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
small problem since one would use <code>boost::array<></code> anyway). Also note
that arrays and pointers of <code >char</code> or <code >whar_t</code> are
treated special because of their use in string algorithms.
</p>
<p > Even though the behavior of the primary templates are exactly such
The concept is defined by the metafunction and the functions below. Even that standard containers will be supported by default, the requirements
though these functions are defined in namespace <code>boost</code>, there is no are much lower than the standard container requirements. For example,
such general requirement, that is, if one wants to extend the list of supported the utility class <a href="utility_class#iterator_range"><code>iterator_range</code></a> implements the minimal interface required to make the class
types, it can be done in any namespace. a <a href="range.htm#forward_range">Forward Range</a>.
</p> </p>
<h3 >Synopsis</h3><a name="Synopsis" ></a> <p>
Please also see <a href="range.htm">Range concepts</a> for more details.
</p>
<p > <a name="Synopsis" ></a>
<h3 >Synopsis</h3>
<pre> <p >
<pre>
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
</p> </tr>
<table border="1" cellpadding="5" > <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>
Please notice in tables below that when four lines appear in a
cell, the first line will describe the primary template, the second
line pairs of iterators, the third line arrays and the last line
null-terminated strings.
</p>
<h4>Metafunctions</h4>
<p>
<table border="1" cellpadding="5" >
<tr > <tr >
<th >Expression</th> <th >Expression</th>
<th >Return type</th> <th >Return type</th>
@ -179,76 +221,93 @@ 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>
<table border="1" cellpadding="5" > <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" >
<tr > <tr >
<th >Expression</th> <th >Expression</th>
<th >Return type</th> <th >Return type</th>
@ -257,102 +316,69 @@ 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>
<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>
<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>

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>