*** empty log message ***

[SVN r24315]
This commit is contained in:
Thorsten Jørgen Ottosen
2004-08-05 19:37:40 +00:00
parent 9657ab7b2b
commit 3e632e0a32
10 changed files with 1135 additions and 738 deletions

View File

@@ -1,112 +1,128 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Boost.Range External Range Implementation </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head> <body><table ><tr ><td ><img src="cboost.gif" width="100%" border="0"></td><td ><h1 ><br>Boost.Range External Range Implementation </h1></td></tr></table><ul ><li ><a href="#Introduction" >Introduction</a></li><li ><a href="#Reference" >Reference</a></li><ul ><li ><a href="#Synopsis" >Synopsis</a></li><li ><a href="#Library headers" >Library headers</a></li><li ><a href="#Semantics" >Semantics</a></li></ul><li ><a href="#Examples" >Examples</a></li><li ><a href="#Portability" >Portability</a></li><li ><a href="#FAQ" >FAQ</a></li><li ><a href="#History" >History</a></li></ul><hr size="1" ><h2 >Introduction</h2><a name="Introduction" ></a><p >This library makes it possible to treat different types as if they have <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
implemented a subset of the container requirements <html>
(see &sect;23.1of the C++ standard). Formally, that subset is defined by <head>
the <a href="Collection.htm" target="_self" >CollectionConcept.</a> <title>Boost.Range Range Implementation </title>
The subset deals mostly with <meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1">
iterator returning functions and nested <code >typedef</code>s. </head>
The main goal is to treat built-in arrays, standard containers,
pairs of iterators and some iterators uniformly. Formally, this library is an implementation
of the <a href="#ExternalCollectionConcept" >ExternalCollectionConcept</a> (see also this explanation of <a href="external_concepts.html" target="_self" >External Concepts</a> ).</p><p >The main advantages are <ul ><li >safe use of built-in arrays</li><li >simpler implementation of generic container algorithms</li><li >more flexible client code</li><li >correct handling of null-terminated strings</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> ):<pre >
//
// Example: extracting bounds in generic algorithms
//
template&lt; typename ExternalCollection, typename T &gt;
inline typename boost::iterator_of&lt;ExternalCollection&gt;::type
find( ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template&lt; typename ExternalCollection, typename T &gt; <body>
inline typename boost::const_iterator_of&lt;ExternalCollection&gt;::type
find( const ExternalCollection& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value ); <table >
} <tr >
<td ><img src="cboost.gif" width="100%" border="0"></td>
// <td ><h1 ><br>
// replace first value and return its index Boost.Range </h1></td>
// </tr>
template&lt; typename EC, typename T &gt; </table>
inline typename boost::size_type_of&lt; EC &gt;::type
my_generic_replace( EC& c, const T& value, const T& replacement ) <h2>Range and ReversibleRange Implementation</h2>
{
typename boost::const_iterator_of&lt;EC&gt;::type found = find( c, value ); <ul >
*found = replacement; <li>
return std::distance( boost::begin( c ), found ); <a href="#overview">Overview</a>
} <li >
<a href="#Synopsis" >Synopsis</a>
// </li>
// usage <li >
// <a href="#Semantics" >Semantics</a>
std::vector&lt;int&gt; my_vector; </li>
typedef vector&lt;int&gt;::iterator iterator; <li >
std::pair&lt;iterator,iterator&gt; my_view( my_vector.begin(), my_vector.begin() + N ); <a href="#Examples" >Examples</a>
char str[] = "a string"; </li>
// ... </ul>
std::cout &lt;&lt; my_generic_replace( my_vector, 4, 2 ) <hr size="1" >
&lt;&lt; my_generic_replace( my_view, 4, 2 )
&lt;&lt; my_generic_replace( str, 'a', 'b' ); <h3>Overview</h3>
</pre>By using the free-standing functions and type-generators, the code automatically <p>
works for all the types supported by this library. Notice that we have to provide Five types of objects are currently supported by the library:
two version of <code >find()</code> since we cannot <ul >
forward a non-const rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The Forwarding Problem</a> ).</p><hr size="1" ><h2 >Reference</h2><a name="Reference" ></a><p ><pre >#include &lt;boost/collection_traits.hpp&gt;</pre></p><p >Five types of objects are currently supported by the library:<ul ><li >standard containers</li><li >built-in arrays</li><li >null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,<code >char*</code>, and <code >wchar_t*</code>)</li><li ><code >std::pair&lt;iterator,iterator&gt;</code></li><li >iterators which when default constructed denotes the end of the range</li></ul>It is worth noticing that some functionality requires partial template specialization, in particular, <li >
full array support does (remark: this is a very small problem since one would use <code>boost::array<></code> standard containers
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><h3 >ExternalCollectionConcept</h3><a name="ExternalCollectionConcept" ></a><p >The concept is defined by the type-generators and the </li>
functions below. Even though these functions are defined in <li >
namespace <code>boost</code>, there is no such general requirement, that is, built-in arrays
if one wants to extend the list of supported types, it can be done in any </li>
namespace.</p><h3 >Synopsis</h3><a name="Synopsis" ></a><p ><pre> <li >
namespace boost null terminated strings (this includes <code >char[]</code>,<code >wchar_t[]</code>,
<code >char*</code>, and <code >wchar_t*</code>)
</li>
<li >
<code >std::pair&lt;iterator,iterator&gt;</code>
</li>
<li >
iterators which when default constructed denotes the end of the range
</li>
</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>
<h3 >ExternalCollectionConcept</h3><a name="ExternalCollectionConcept" ></a>
<p >
The concept is defined by the type-generators and the functions below. Even
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>
<h3 >Synopsis</h3><a name="Synopsis" ></a>
<p >
<pre>
namespace boost
{ {
// //
// type generators // type generators
// //
template< typename EC > template< typename EC >
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 objects typedef ... type; // type of stored objects
}; };
template< typename EC > template< typename EC >
struct <a href="#iterator_of" >iterator_of</a> struct <a href="#iterator_of" >iterator_of</a>
{ {
typedef ... type; // iterator over stored objects typedef ... type; // iterator over stored objects
}; };
template< typename EC > template< typename EC >
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 typedef ... type; // iterator over immutable stored objects
}; };
template< typename EC > template< typename EC >
struct <a href="#difference_type_of" >difference_type_of</a> struct <a href="#difference_type_of" >difference_type_of</a>
{ {
typedef ... type; typedef ... type;
BOOST_STATIC_ASSERT( boost::is_signed< type >::value ); BOOST_STATIC_ASSERT( boost::is_signed< type >::value );
// //
// remark: if std::iterator_traits<> works for the type, this assertion must hold // remark: if std::iterator_traits<> works for the type, this assertion must
hold
// //
BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename BOOST_STATIC_ASSERT( boost::is_same< type, std::iterator_traits< typename
<a href="#iterator_of" >iterator_of</a>< EC >::type >::difference_type>::value ); <a href="#iterator_of" >iterator_of</a>< EC >::type >::difference_type>::value );
}; };
template< typename EC > template< typename EC >
struct <a href="#size_type_of" >size_type_of</a> struct <a href="#size_type_of" >size_type_of</a>
{ {
typedef ... type; typedef ... type;
BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value ); BOOST_STATIC_ASSERT( boost::is_unsigned< type >::value );
BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( <a href="#difference_type_of" >difference_type_of</a>< EC >::type ) ); BOOST_STATIC_ASSERT( sizeof( type ) >= sizeof( <a href="#difference_type_of" >
difference_type_of</a>< EC >::type ) );
}; };
template< typename EC > template< typename EC >
struct <a href="#result_iterator_of" >result_iterator_of</a> struct <a href="#result_iterator_of" >result_iterator_of</a>
{ {
typedef ... type; typedef ... type;
// <a href="#iterator_of" >iterator_of</a>< EC >::type if EC is non-const, <a href="#const_iterator_of" >const_iterator_of</a>< EC >::type otherwise // <a href="#iterator_of" >iterator_of</a>< EC >::type if EC is non-const, <a href="#const_iterator_of" >
const_iterator_of</a>< EC >::type otherwise
}; };
// //
@@ -115,15 +131,15 @@
template< typename EC > template< typename EC >
inline typename iterator_of<EC>::type inline typename iterator_of<EC>::type
<a href="#begin" >begin</a>( EC& c ); <a href="#begin" >begin</a>( EC& c );
template< typename EC > template< typename EC >
inline typename const_iterator_of< EC >::type inline typename const_iterator_of< EC >::type
<a href="#begin" >begin</a>( const EC& c ); <a href="#begin" >begin</a>( const EC& c );
template< typename EC > template< typename EC >
inline typename iterator_of< EC >::type inline typename iterator_of< EC >::type
<a href="#end" >end</a>( EC& c ); <a href="#end" >end</a>( EC& c );
template< typename EC > template< typename EC >
inline typename const_iterator_of< EC >::type inline typename const_iterator_of< EC >::type
@@ -131,38 +147,230 @@
template< typename EC > template< typename EC >
inline bool inline bool
<a href="#empty" >empty</a>( const EC& c ); <a href="#empty" >empty</a>( const EC& c );
template< typename EC > template< typename EC >
inline typename size_type_of< EC >::type inline typename size_type_of< EC >::type
<a href="#size" >size</a>( const EC& c ); <a href="#size" >size</a>( const EC& c );
} // namespace 'boost' </pre></p><h3 >Library headers</h3><a name="Library headers" ></a><table cellpadding=5 border=1 > <tr ><th >Header</th><th >Includes</th></tr><tr ><td ><code >&lt;boost/collection_traits.hpp&gt;</code></td><td >everything</td></tr><tr ><td ><code >&lt;boost/collection_traits/types.hpp&gt;</code></td><td >every type-generator</td></tr><tr ><td ><code >&lt;boost/collection_traits/functions.hpp&gt;</code></td><td >every function</td></tr><tr ><td ><code >&lt;boost/collection_traits/value_type.hpp&gt;</code></td><td ><a href="#value_type_of" >value_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/iterator.hpp&gt;</code></td><td ><a href="#iterator_of" >iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/const_iterator.hpp&gt;</code></td><td ><a href="#const_iterator_of" >const_iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/difference_type.hpp&gt;</code></td><td ><a href="#difference_type_of" >difference_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/size_type.hpp&gt;</code></td><td ><a href="#size_type_of" >size_type_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/result_iterator.hpp&gt;</code></td><td ><a href="#result_iterator_of" >result_iterator_of</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/begin.hpp&gt;</code></td><td ><a href="#begin" >begin</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/end.hpp&gt;</code></td><td ><a href="#end" >end</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/empty.hpp&gt;</code></td><td ><a href="#empty" >empty</a></td></tr><tr ><td ><code >&lt;boost/collection_traits/size.hpp&gt;</code></td><td ><a href="#size" >size</a></td></tr> </table><br><h3 >Semantics</h3><a name="Semantics" ></a><p >In the table <code >C</code> is a type that conforms to the ExternalCollectionConcept and <code >c</code> is an object of that type.<code > SC</code> will denote a standard } // namespace 'boost' </pre>
container, <code > T[sz]</code> will denote an array of type <code >T</code> of size <code >sz</code>, <code >P</code> will denote <code >std::pair&lt;&gt;</code>, <code > I</code> means an iterator which default construction </p>
denotes the end of the range and <code >sc,t,p,i</code> are objects of these types,
respectively. Special cases for <code >char*</code> and <code >wchar_t*</code> are described explicitly. </p><table border=1 cellpadding=5 > <tr ><th >Expression</th><th >Return type</th><th >Complexity</th></tr><tr ><a name="value_type_of" ></a><td ><code >value_type_of&lt;C&gt;::type</code></td><td ><code >SC::value_type</code><br><code >T</code><br><code >std::iterator_traits&lt;P::first_type&gt;::value_type</code><br><code >std::iterator_traits&lt;I&gt;::value_type</code></td><td >compile time</td></tr><tr ><a name="iterator_of" ></a><td ><code >iterator_of&lt;C&gt;::type</code></td><td ><code >SC::iterator</code><br><code >T*</code><br><code >P::first_type</code><br><code >I</code></td><td >compile time</td></tr><tr ><a name="const_iterator_of" ></a><td ><code >const_iterator_of&lt;C&gt;::type</code></td><td ><code >SC::const_iterator</code><br><code >const T*</code><br><code >P::first_type</code><br><code >I</code></td><td >compile time</td></tr><tr ><a name="difference_type_of" ></a><td ><code >difference_type_of&lt;C&gt;::type</code></td><td ><code >SC::difference_type</code><br><code >std::ptrdiff_t</code><br><code >std::iterator_traits&lt;P::first_type&gt;::difference_type</code><br><code >std::iterator_traits&lt;I&gt;::difference_type</code></td><td >compile time</td></tr><tr ><a name="size_type_of" ></a><td ><code >size_type_of&lt;C&gt;::type</code></td><td ><code >SC::size_type</code><br><code >std::size_t</code><br><code >std::size_t</code><br><code >std::size_t</code></td><td >compile time</td></tr><tr ><a name="result_iterator_of" ></a><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >const_iterator_of&lt;C&gt;::type</code> if <code >C</code> is <code >const</code><br><code >iterator_of&lt;C&gt;::type</code> otherwise </td><td >compile time</td></tr> </table> <br> <table border=1 cellpadding=5 > <tr ><th >Expression</th><th >Return type</th><th >Effects</th><th >Complexity</th></tr><tr ><a name="begin" ></a><td ><code >begin( c )</code></td><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >sc.begin()</code><br><code >t</code><br><code >p.first</code><br><code >i</code></td><td >constant time</td></tr><tr ><a name="end" ></a><td ><code >end( c )</code></td><td ><code >result_iterator_of&lt;C&gt;::type</code></td><td ><code >sc.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 >I()</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br>constant time otherwise</td></tr><tr ><a name="empty" ></a><td ><code >empty( c )</code></td><td >Convertible to <code >bool</code></td><td ><code >sc.empty()</code><br><code >size( t ) == 0</code><br><code >p.first == p.second</code><br><code >begin( i ) == end( i )</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br>constant time otherwise<br></td></tr><tr ><a name="size" ></a><td ><code >size( c )</code></td><td ><code >size_type_of&lt;C&gt;::type</code></td><td ><code >sc.size()</code><br><code >end( t ) - begin( t )</code><br><code >distance( p.first, p.second )</code><br><code >not available for iterators</code></td><td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code><br> or if <code >std::distance()</code> is linear <br>constant time otherwise</td></tr> </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>. <h3 >Semantics</h3><a name="Semantics" ></a>
Note that the null pointer is allowed as an argument in these cases.</p><br><hr size="1" ><h2 >Examples</h2><a name="Examples" ></a><p >Some examples are given in the accompanying test <p >
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 size="1" ><h2 >Portability</h2><a name="Portability" ></a><p >Full support for built-in arrays require that the In the table <code >C</code> is a type that conforms to the
compiler supports class template partial specialization.</p><p >Notice that some compilers cannot do function template ordering ExternalCollectionConcept and <code >c</code> is an object of that type.<code >
properly. In that case one cannot rely of <code >result_iterator_of&lt;&gt;</code> and a single function definition; instead one needs to supply SC</code>
a function overloaded for const and non-const arguments if it is required.</p><p >Full support for iterators like <code >std::istream_iterator&lt;&gt;</code> depends very will denote a standard container, <code >T[sz]</code> will denote an array of
much on a conforming standard library.</p><p >Most of the tests have been run successfully on these compilers<ul ><li >vc7.1</li><li >gcc3.2</li><li >como4.3.0.1</li><li >bcc6</li></ul></p><hr size="1" ><h2 >FAQ</h2><a name="FAQ" ></a><ol ><li >Why is there no difference between <code >iterator_of&lt;C&gt;::type</code> and <code >const_iterator_of&lt;C&gt;::type</code> for <code >std::pair&lt;iterator,iterator&gt;</code> or iterators which default construction denotes the end of the range?</li><p >In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>. When it is possible to come up with type <code >T</code> of size <code >sz</code>, <code >P</code> will denote <code >
one, the client might choose to std::pair&lt;&gt;</code>,
construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code> object. </p><li >Why does the traits not supply more types or more functions?<p >The traits class have been kept small because its current interface <code >I</code> means an iterator which default construction denotes the end of
will serve most purposes. If and when a genuine need arises for the range and <code >sc,t,p,i</code> are objects of these types, respectively.
more functionality, it can be implemented.</p></li><li >How should I implement generic algorithms for external collections?<p >One should always start with a generic algorithm that takes two iterators as input. Then use the Special cases for <code >char*</code> and <code >wchar_t*</code> are described
collection traits to build handier versions on top of the base algorithm.</p></li></ol><hr size="1" ><h2 >History</h2><a name="History" ></a><p >The library have been under way for a long time. Dietmar K<>hl originally explicitly.
intended to submit an <code >array_traits&lt;&gt;</code> class template which had most </p>
of the functionality present now, but only for arrays and standard containers. <table border="1" cellpadding="5" >
Meanwhile work on container algorithms <tr >
in various context showed the need for handling pairs of iterators, and <th >Expression</th>
string libraries needed special treatment of character arrays. <th >Return type</th>
Thorsten Ottosen wrote everything from the ground up including the first <th >Complexity</th>
work-around for missing partial template specialization. Pavol Droba helped to </tr>
improve the work-around for handicapped compilers and the special character support. <tr >
The naming scheme of type-generators was suggested by Peter Dimov. </p><hr size="1" ><p >&copy; Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk). <a name="value_type_of" ></a>
Permission to copy, use, modify, sell and distribute this software is granted provided this copyright notice appears <td ><code >value_type_of&lt;C&gt;::type</code></td>
in all copies. This software is provided "as is" without express or implied warranty, and with no <td ><code >SC::value_type</code><br>
claim as to its suitability for any purpose.</p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></body></html> <code >T</code><br>
<!-- Copyright Dezide Aps 2003-2004 --> <code >std::iterator_traits&lt;P::first_type&gt;::value_type</code><br>
<td >compile time</td>
</tr>
<tr >
<a name="iterator_of" ></a>
<td ><code >iterator_of&lt;C&gt;::type</code></td>
<td ><code >SC::iterator</code><br>
<code >T*</code><br>
<code >P::first_type</code><br>
<td >compile time</td>
</tr>
<tr >
<a name="const_iterator_of" ></a>
<td ><code >const_iterator_of&lt;C&gt;::type</code></td>
<td ><code >SC::const_iterator</code><br>
<code >const T*</code><br>
<code >P::first_type</code><br>
<td >compile time</td>
</tr>
<tr >
<a name="difference_type_of" ></a>
<td ><code >difference_type_of&lt;C&gt;::type</code></td>
<td ><code >SC::difference_type</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>
</tr>
<tr >
<a name="size_type_of" ></a>
<td ><code >size_type_of&lt;C&gt;::type</code></td>
<td ><code >SC::size_type</code><br>
<code >std::size_t</code><br>
<code >std::size_t</code><br>
<td >compile time</td>
</tr>
<tr >
<a name="result_iterator_of" ></a>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >const_iterator_of&lt; C&gt;::type</code> if <code >C</code> is <code >
const</code>
<br>
<code >iterator_of&lt;C&gt;::type</code> otherwise </td>
<td >compile time</td>
</tr>
<tr >
<a name="reverse_iterator_of" ></a>
<td ><code >reverse_iterator_of&lt;C&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename iterator_of&lt;T>::type
></code><br> <td >compile time</td>
</tr>
<tr >
<a name="const_reverse_iterator_of" ></a>
<td ><code >const_reverse_iterator_of&lt;C&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename const_iterator_of&lt;T>::type ></code><br>
<td >compile time</td>
</tr> <tr >
<a name="reverse_result_iterator_of" ></a>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >boost::reverse_iterator< typename result_iterator_of&lt;T&gt;::
type ></code>
<td >compile time</td>
</tr>
</table>
<br>
<table border="1" cellpadding="5" >
<tr >
<th >Expression</th>
<th >Return type</th>
<th >Returns</th>
<th >Complexity</th>
</tr>
<tr >
<a name="begin" ></a>
<td ><code >begin( c )</code></td>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >sc.begin()</code><br>
<code >t</code><br>
<code >p.first</code><br>
<td >constant time</td>
</tr>
<tr >
<a name="end" ></a>
<td ><code >end( c )</code></td>
<td ><code >result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >sc.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>
<td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code>
<br>
constant time otherwise</td>
</tr>
<tr >
<a name="empty" ></a>
<td ><code >empty( c )</code></td>
<td >Convertible to <code >bool</code></td>
<td ><code >sc.empty()</code><br>
<code >size( t ) == 0</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>
</td>
</tr>
<tr >
<a name="size" ></a>
<td ><code >size( c )</code></td>
<td ><code >size_type_of&lt;C&gt;::type</code></td>
<td ><code >sc.size()</code><br>
<code >end( t ) - begin( t )</code><br>
<code >distance( p. first, p.second )</code><br>
<td >linear if <code >C</code> is <code >char*</code> or <code >wchar_t*</code>
<br>
or if <code >std::distance()</code> is linear <br>
constant time otherwise</td>
</tr>
<tr >
<a name="rbegin" ></a>
<td ><code >rbegin( c )</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type( end( c ) )</code>
<br>
<td >same as <code>end()</code> </td>
</tr>
<tr >
<a name="rend" ></a>
<td ><code >rend( c )</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type</code></td>
<td ><code >reverse_result_iterator_of&lt;C&gt;::type( begin( c ) )</code>
<td > same as <code>begin()</code></td>
</tr>
</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>
<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>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

75
doc/faq.html Executable file
View File

@@ -0,0 +1,75 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range FAQ </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range</h1></td>
</tr>
</table>
<p>
<h2 >FAQ</h2>
<a name="FAQ" ></a>
<ol >
<li >
Why is there no difference between <code >iterator_of&lt;C&gt;::type</code> and <code >const_iterator_of&lt;C&gt;::type</code>
for <code >std::pair&lt;iterator, iterator&gt;</code>.
</li>
<p >
In general it is not possible nor desirable to find a corresponding <code >const_iterator</code>.
When it is possible to come up with one, the client might choose to construct a <code >std::pair&lt;const_iterator,const_iterator&gt;</code>
object.
</p>
<li >
Why is there not supplied more types or more functions?
<p >
The library have been kept small because its current interface will serve
most purposes. If and when a genuine need arises for more functionality, it can
be implemented.
</p>
</li>
<li >
How should I implement generic algorithms for ranges?
<p >
One should always start with a generic algorithm that takes two
iterators (or more) as
input. Then use Boost.Range to build handier versions on top of the
iterator based algorithm. Please notice that once the range version
of the algorithm is done, it makes sense <i>not</i> to expose the
iterator version in the public interface.
</p>
</li>
</ol>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

134
doc/headers.html Executable file
View File

@@ -0,0 +1,134 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range Headers </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range</h1></td>
</tr>
</table>
<p>
<h2 >Library headers</h2><a name="Library headers" ></a>
<table cellpadding="5" border="1" >
<tr >
<th >Header</th>
<th >Includes</th>
</tr>
<tr >
<td ><code >&lt;boost/range.hpp&gt;</code></td>
<td >everything</td>
</tr>
<tr >
<td ><code >&lt;boost/range/types.hpp&gt;</code></td>
<td >every meta-function</td>
</tr>
<tr >
<td ><code >&lt;boost/range/functions.hpp&gt;</code></td>
<td >every function</td>
</tr>
<tr >
<td ><code >&lt;boost/range/value_type.hpp&gt;</code></td>
<td ><a href="boost_range.html#value_type_of" >value_type_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#iterator_of" >iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/const_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#const_iterator_of" >const_iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/difference_type.hpp&gt;</code></td>
<td ><a href="boost_range.html#difference_type_of" >difference_type_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/size_type.hpp&gt;</code></td>
<td ><a href="boost_range.html#size_type_of" >size_type_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/result_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#result_iterator_of" >result_iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/reverse_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#reverse_iterator_of" >reverse_iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/const_reverse_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#const_reverse_iterator_of" >const_reverse_iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/reverse_result_iterator.hpp&gt;</code></td>
<td ><a href="boost_range.html#reverse_result_iterator_of">reverse_result_iterator_of</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/begin.hpp&gt;</code></td>
<td ><a href="boost_range.html#begin" >begin</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/end.hpp&gt;</code></td>
<td ><a href="boost_range.html#end" >end</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/empty.hpp&gt;</code></td>
<td ><a href="boost_range.html#empty" >empty</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/size.hpp&gt;</code></td>
<td ><a href="boost_range.html#size" >size</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/rbegin.hpp&gt;</code></td>
<td ><a href="boost_range.html#rbegin" >rbegin</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/rend.hpp&gt;</code></td>
<td ><a href="boost_range.html#rend" >rend</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/iterator_range.hpp&gt;</code></td>
<td ><a href="utility_class.html#iter_range"
>iterator_range</a></td>
</tr>
<tr >
<td ><code >&lt;boost/range/sub_range.hpp&gt;</code></td>
<td ><a href="utility_class.html#sub_range" >sub_range</a></td>
</tr>
</table>
<br
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

62
doc/history_ack.html Executable file
View File

@@ -0,0 +1,62 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range History and Acknowledgement </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range </h1></td>
</tr>
</table>
<h2 >History and Acknowledgement</h2><a name="History" ></a>
<p >
The library have been under way for a long time. Dietmar K<>hl originally
intended to submit an <code >array_traits&lt;&gt;</code> class template which
had most of the functionality present now, but only for arrays and standard
containers.
</p>
<p>
Meanwhile work on container algorithms in various context showed the
need for handling pairs of iterators, and string libraries needed special
treatment of character arrays.
</p>
<p>
Special thanks goes to
<ul>
<li> Pavol Droba
<li> Pavel Vozenilek
<li> Jonathan Turkanis
</ul>
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

125
doc/intro.html Executable file
View File

@@ -0,0 +1,125 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range Introduction </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range</h1></td>
</tr>
</table>
<h2>Introduction</h2>
<p>
This library makes it possible to treat different types as if they have
implemented a subset of the container requirements (see &sect;23.1of the C++
standard). Formally, that subset is defined by the <a href="Range.htm"
target="_self" >Range</a> concept. The subset deals mostly with iterator
returning functions and nested <code >typedef</code>s. The main goal is to treat
built-in arrays, standard containers, pairs of iterators and some iterators
uniformly.
</p>
<p >
The main advantages are
<ul >
<li >
safe use of built-in arrays
</li>
<li >
simpler implementation of generic container algorithms
</li>
<li >
more flexible client code
</li>
<li >
correct handling of null-terminated strings
</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>
):
<pre >
//
// Example: extracting bounds in generic algorithms
//
template&lt; typename XRange, typename T &gt;
inline typename boost::iterator_of&lt;XRange&gt;::type
find( XRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
template&lt; typename XRange, typename T &gt;
inline typename boost::const_iterator_of&lt;XRange&gt;::type
find( const XRange& c, const T& value )
{
return std::find( boost::begin( c ), boost::end( c ), value );
}
//
// replace first value and return its index
//
template&lt; typename EC, typename T &gt;
inline typename boost::size_type_of&lt; EC &gt;::type
my_generic_replace( EC& c, const T& value, const T& replacement )
{
typename boost::const_iterator_of&lt;EC&gt;::type found = find( c, value );
*found = replacement;
return std::distance( boost::begin( c ), found );
}
//
// usage
//
std::vector&lt;int&gt; my_vector;
typedef vector&lt;int&gt;::iterator iterator;
std::pair&lt;iterator,iterator&gt; my_view( my_vector.begin(), my_vector.begin(
) + N );
char str[] = "a string";
// ...
std::cout &lt;&lt; my_generic_replace( my_vector, 4, 2 )
&lt;&lt; my_generic_replace( my_view, 4, 2 )
&lt;&lt; my_generic_replace( str, 'a', 'b' );
</pre>
By using the free-standing functions and type-generators, the code automatically
works for all the types supported by this library. Notice that we have to
provide two version of <code >find()</code> since we cannot forward a non-const
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
Forwarding Problem</a> ).
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>

63
doc/portability.html Executable file
View File

@@ -0,0 +1,63 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range Portability </title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<table border="0" >
<tr>
<td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range</h1></td>
</tr>
</table>
<h2>Portability</h2><a name="Portability" ></a>
<p >
Full support for built-in arrays require that the compiler supports class
template partial specialization. For non-conforming compilers there might
be a change that it works anyway thanks to workarounds in the type traits
library. </p>
<p >
Notice that some compilers cannot do function template ordering properly. In
that case one must rely of <code >result_iterator_of&lt;&gt;</code> and a
single function definition instead of
overloaded versions for const and non-const arguments.
So if one cares about old compilers, one should not pass rvalues
to the functions.
</p>
<p>
A huge effort has been made to port the library to as many compilers as
possible. The results of the test-suites can be found
<a href="http://boost.sourceforge.net/regression-logs/developer/range.html">here</a>.
</p>
<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

@@ -11,181 +11,112 @@
-- purpose. It is provided "as is" without express or implied warranty. -- purpose. It is provided "as is" without express or implied warranty.
--> -->
<Head> <Head>
<Title>Range Concepts</Title> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<Title>Range Concepts</Title>
<link rel="stylesheet" href="style.css" type="text/css">
</HEAD> </HEAD>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="cboost.gif"
ALT="C++ Boost">
<IMG SRC="/Images/stat.gif" ALT="" BORDER=0 WIDTH = "6" HEIGHT = "6" >
<BR Clear> <table border="0" >
<a name=range> <tr>
<H1>Range</H1> <td ><img src="cboost.gif" border="0" ></td>
<td ><h1 align="center">Boost.Range </h1></td>
</tr>
</table>
<h2>Range concepts </h2>
<ul>
<li>
<a href="#range">Range</a>
<li>
<a href="#reversible_range">ReversibleRange</a>
</ul>
<hr>
<a name="range"><H1>Range</H1>
<h3>Description</h3> <h3>Description</h3>
A Range is a <i>concept</i> similar to the STL <a A Range is a <i>concept</i> similar to the STL <a
href="http://www.sgi.com/Technology/STL/Container.html">Container</a> href="http://www.sgi.com/Technology/STL/Container.html">Container</a> concept. A
concept. A Range provides iterators for accessing a range of Range provides iterators for accessing a range of elements and provides
elements and provides information about the number of elements in the information about the number of elements in the Range. However, a Range has
Range. However, a Range has fewer requirements than a fewer requirements than a Container. The motivation for the Range concept is
Container. The motivation for the Range concept is that there are that there are many useful Container-like types that do not meet the full
many useful Container-like types that do not meet the full requirements of Container, and many algorithms that can be written with this
requirements of Container, and many algorithms that can be written reduced set of requirements. In particular, a Range does not necessarily
with this reduced set of requirements. In particular, a Range does
not necessarily
<ul> <ul>
<li> own the elements that can be accessed through it, <li>
<li> have copy semantics, own the elements that can be accessed through it,
<li> require that the associated reference type is a real C++ reference. <li>
have copy semantics,
<li>
require that the associated reference type is a real C++ reference.
</ul> </ul>
Because of the second requirement, a Range object must Because of the second requirement, a Range object must be passed by reference in
be passed by reference in generic code. generic code.
<p> <p>
<h3>Notation</h3> <h3>Notation</h3>
<Table> <Table>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top"><tt>X</tt></TD>
<tt>X</tt> <TD VAlign="top">A type that is a model of Range.</TD>
</TD> </TR>
<TD VAlign=top> <TR>
A type that is a model of Range. <TD VAlign="top"><tt>a</tt>, <tt>b</tt></TD>
</TD> <TD VAlign="top">Object of type <tt>X</tt>.</TD>
</TR> </TR>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top"><tt>T</tt></TD>
<tt>a</tt>, <tt>b</tt> <TD VAlign="top">The value type of <tt>X</tt>.</TD>
</TD> </tr>
<TD VAlign=top>
Object of type <tt>X</tt>.
</TD>
</TR>
<TR>
<TD VAlign=top>
<tt>T</tt>
</TD>
<TD VAlign=top>
The value type of <tt>X</tt>.
</TD>
</tr>
</table> </table>
<h3>Associated types</h3> <h3>Associated types</h3>
<Table border> <table border=1 cellpadding=5>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top">Value type</TD>
Value type <TD VAlign="top"><tt>value_type_of&lt;X>::type</tt></TD>
</TD> <TD VAlign="top">The type of the object stored in a Range.
<TD VAlign=top> </TR>
<tt>X::value_type</tt> <TR>
</TD> <TD VAlign="top">Iterator type</TD>
<TD VAlign=top> <TD VAlign="top"><tt>iterator_of&lt;X>::type</tt></TD>
The type of the object stored in a Range. <TD VAlign="top">The type of iterator used to iterate through a Range's elements.
<!-- The iterator's value type is expected to be the Range's value type. A
If the Collection is <i>mutable</i> then conversion from the iterator type to the const iterator type must exist. The
the value type must be <A iterator type must at least be an <A
href="http://www.sgi.com/Technology/STL/Assignable.html">Assignable</A>. href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</A>.</TD>
Otherwise the value type must be <a href="./CopyConstructible.html">CopyConstructible</a>. </TR>
--> <TR>
</TD> <TD VAlign="top">Const iterator type</TD>
</TR> <TD VAlign="top"><tt>const_iterator_of&lt;X>::type</tt></TD>
<TR> <TD VAlign="top">A type of iterator that may be used to examine, but not to
<TD VAlign=top> modify, a Range's elements.</TD>
Iterator type </TR>
</TD> <TR>
<TD VAlign=top> <TD VAlign="top">Reference type</TD>
<tt>X::iterator</tt> <TD VAlign="top"><tt>reference_of&lt;X>::type</tt></TD>
</TD> <TD VAlign="top">A type that behaves like a reference to the Range's value type. <a href="#1">[1]</a></TD>
<TD VAlign=top> </TR>
The type of iterator used to iterate through a Range's <TR>
elements. The iterator's value type is expected to be the <TD VAlign="top">Distance type</TD>
Range's value type. A conversion <TD VAlign="top"><tt>difference_type_of&lt;>::type</tt></TD>
from the iterator type to the const iterator type must exist. <TD VAlign="top">A signed integral type used to represent the distance between
The iterator type must at least be an <A two of the Range's iterators. This type must be the same as the iterator's
href="http://www.sgi.com/Technology/STL/InputIterator.html">InputIterator</A>. distance type.</TD>
</TD> </TR>
</TR> <TR>
<TR> <TD VAlign="top">Size type</TD>
<TD VAlign=top> <TD VAlign="top"><tt>size_type_of&lt;X>::type</tt></TD>
Const iterator type <TD VAlign="top">An unsigned integral type that can represent any nonnegative
</TD> value of the Range's distance type.</TD>
<TD VAlign=top> </tr>
<tt>X::const_iterator</tt>
</TD>
<TD VAlign=top>
A type of iterator that may be used to examine, but not to modify,
a Range's elements.
</TD>
</TR>
<TR>
<TD VAlign=top>
Reference type
</TD>
<TD VAlign=top>
<tt>X::reference</tt>
</TD>
<TD VAlign=top>
A type that behaves like a reference to the Range's value type.
<a href="#1">[1]</a>
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Const reference type
</TD>
<TD VAlign=top>
<tt>X::const_reference</tt>
</TD>
<TD VAlign=top>
A type that behaves like a const reference to the Collection's value type.
</TD>
</TR>
<TR>
<TD VAlign=top>
Pointer type
</TD>
<TD VAlign=top>
<tt>X::pointer</tt>
</TD>
<TD VAlign=top>
A type that behaves as a pointer to the Collection's value type.
</TD>
</TR>
-->
<TR>
<TD VAlign=top>
Distance type
</TD>
<TD VAlign=top>
<tt>X::difference_type</tt>
</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>
<tt>X::size_type</tt>
</TD>
<TD VAlign=top>
An unsigned integral type that can represent any nonnegative value
of the Range's distance type.
</TD>
</tr>
</table> </table>
@@ -194,395 +125,209 @@ An unsigned integral type that can represent any nonnegative value
The following expressions must be valid. The following expressions must be valid.
<p> <p>
<Table border> <Table border=1 cellpadding=5>
<TR> <TR>
<TH> <TH>Name</TH>
Name <TH>Expression</TH>
</TH> <TH>Return type</TH>
<TH> </TR>
Expression <TR>
</TH> <TD VAlign="top">Beginning of range</TD>
<TH> <TD VAlign="top"><tt>begin(a)</tt></TD>
Return type <TD VAlign="top"><tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt>
</TH> otherwise</TD>
</TR> </TR>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top">End of range</TD>
Beginning of range <TD VAlign="top"><tt>end(a)</tt></TD>
</TD> <TD VAlign="top"><tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt>
<TD VAlign=top> otherwise</TD>
<tt>a.begin()</tt> </TR>
</TD> <TR>
<TD VAlign=top> <TD VAlign="top">Size of range</TD>
<tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt> otherwise <TD VAlign="top"><tt>size(a)</tt></TD>
</TD> <TD VAlign="top"><tt>size_type</tt></TD>
</TR> </TR>
<TR> <TD VAlign="top">Is range empty?</TD>
<TD VAlign=top> <TD VAlign="top"><tt>empty(a)</tt></TD>
End of range <TD VAlign="top">Convertible to <tt>bool</tt></TD>
</TD> </TR>
<TD VAlign=top> <TR>
<tt>a.end()</tt> </tr>
</TD>
<TD VAlign=top>
<tt>iterator</tt> if <tt>a</tt> is mutable, <tt>const_iterator</tt> otherwise
</TD>
</TR>
<TR>
<TD VAlign=top>
Size
</TD>
<TD VAlign=top>
<tt>a.size()</tt>
</TD>
<TD VAlign=top>
<tt>size_type</tt>
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
<tt>size_type</tt>
</TD>
</TR>
<TR>
-->
<TD VAlign=top>
Empty range
</TD>
<TD VAlign=top>
<tt>a.empty()</tt>
</TD>
<TD VAlign=top>
Convertible to <tt>bool</tt>
</TD>
</TR>
<TR>
<!--
<TD VAlign=top>
Swap
</TD>
<TD VAlign=top>
<tt>a.swap(b)</tt>
</TD>
<TD VAlign=top>
<tt>void</tt>
</TD> -->
</tr>
</table> </table>
<h3>Expression semantics</h3> <h3>Expression semantics</h3>
<Table border> <Table border>
<TR> <TR>
<TH> <TH>Expression</TH>
Name <TH>Semantics</TH>
</TH> <TH>Postcondition</TH>
<TH> </TR>
Expression <TD VAlign="top">
</TH> <TR>
<TH> <TD VAlign="top"><tt>begin(a)</tt></TD>
Semantics <TD VAlign="top">Returns an iterator pointing to the first element in the Range.</TD>
</TH> <TD VAlign="top"><tt>begin(a)</tt> is either dereferenceable or
<TH> past-the-end. It is past-the-end if and only if <tt>size(a) == 0</tt>.</TD>
Postcondition </TR>
</TH> <TR>
</TR> <TD VAlign="top"><tt>end(a)</tt></TD>
<TD VAlign=top> <TD VAlign="top">Returns an iterator pointing one past the last element in the
<TR> Range.</TD>
<TD VAlign=top> <TD VAlign="top"><tt>end(a)</tt> is past-the-end.</TD>
Beginning of range </TR>
</TD> <TR>
<TD VAlign=top> <TD VAlign="top"><tt>size(a)</tt></TD>
<tt>a.begin()</tt> <TD VAlign="top">Returns the size of the Collection, that is, its number of
</TD> elements.</TD>
<TD VAlign=top> <TD VAlign="top"><tt>size(a) &gt;= 0</TD>
Returns an iterator pointing to the first element in the Range. </TR>
</TD> <TR>
<TD VAlign=top> <TD VAlign="top"><tt>empty(a)</tt></TD>
<tt>a.begin()</tt> is either dereferenceable or past-the-end. It is <TD VAlign="top">Equivalent to <tt>size(a) == 0</tt>. (But
past-the-end if and only if <tt>a.size() == 0</tt>. possibly faster.)</TD> <TD VAlign="top">&nbsp;-&nbsp;</TD>
</TD> </TR>
</TR>
<TR>
<TD VAlign=top>
End of range
</TD>
<TD VAlign=top>
<tt>a.end()</tt>
</TD>
<TD VAlign=top>
Returns an iterator pointing one past the last element in the
Range.
</TD>
<TD VAlign=top>
<tt>a.end()</tt> is past-the-end.
</TD>
</TR>
<TR>
<TD VAlign=top>
Size
</TD>
<TD VAlign=top>
<tt>a.size()</tt>
</TD>
<TD VAlign=top>
Returns the size of the Collection, that is, its number of elements.
</TD>
<TD VAlign=top>
<tt>a.size() &gt;= 0
</TD>
</TR>
<!--
<TR>
<TD VAlign=top>
Maximum size
</TD>
<TD VAlign=top>
<tt>a.max_size()</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
<TD VAlign=top>
Returns the largest size that this Collection can ever have. <A href="#8">[8]</A>
</TD>
<TD VAlign=top>
<tt>a.max_size() &gt;= 0 &amp;&amp; a.max_size() &gt;= a.size()</tt>
</TD>
</TR>
-->
<TR>
<TD VAlign=top>
Empty Collection
</TD>
<TD VAlign=top>
<tt>a.empty()</tt>
</TD>
<TD VAlign=top>
Equivalent to <tt>a.size() == 0</tt>. (But possibly faster.)
</TD>
<TD VAlign=top>
&nbsp;
</TD>
</TR>
<TR>
<!--
<TD VAlign=top>
Swap
</TD>
<TD VAlign=top>
<tt>a.swap(b)</tt>
</TD>
<TD VAlign=top>
Equivalent to <tt>swap(a,b)</tt>
</TD>
<TD VAlign=top>
&nbsp;
</TD>
-->
</tr>
</table> </table>
<h3>Complexity guarantees</h3> <h3>Complexity guarantees</h3>
All four functions are at most amortized linear time. For All four functions are at most amortized linear time. For most practical
most practical purposes, one can expect purposes, one can expect <tt>begin(a)</tt>, <tt>end(a)</tt> and
<tt>begin()</tt>, <tt>end()</tt> and <tt>empty()</tt> to be amortized constant <tt>empty(a)</tt> to be amortized constant time.
time.
<h3>Invariants</h3> <h3>Invariants</h3>
<Table border> <Table border>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top">Valid range</TD>
Valid range <TD VAlign="top">For any Range <tt>a</tt>, <tt>[begin(a),end(a))</tt> is a
</TD> valid range, that is, <code>end(a)</code> is reachable from <code>begin(a)</code>
<TD VAlign=top> in a finite number of increments.</TD>
For any Range <tt>a</tt>, <tt>[a.begin(), a.end())</tt> is a valid </TR>
range. <TR>
</TD> <TD VAlign="top">Range size</TD>
</TR> <TD VAlign="top"><tt>size(a)</tt> is equal to the distance from
<TR> <tt>begin(a)</tt> to <tt>end(a)</tt>.</TD>
<TD VAlign=top> </TR>
Range size <TR>
</TD> <TD VAlign="top">Completeness</TD>
<TD VAlign=top> <TD VAlign="top">An algorithm that iterates through the range
<tt>a.size()</tt> is equal to the distance from <tt>a.begin()</tt> to <tt>a.end()</tt>. <tt>[begin(a),end(a))</tt> will pass through every element of <tt>a</tt>.</TD>
</TD> </tr>
</TR>
<TR>
<TD VAlign=top>
Completeness
</TD>
<TD VAlign=top>
An algorithm that iterates through the range <tt>[a.begin(), a.end())</tt>
will pass through every element of <tt>a</tt>.
</TD>
</tr>
</table> </table>
<h3>Models</h3> <h3>Models</h3>
<UL> <UL>
<LI> <tt>boost::array&lt;T,sz></tt> <li>
<LI> <tt>std::vector&lt;bool&gt;</tt> <code>All models of <A href="http://www.sgi.com/Technology/STL/Container.html">Container</A></code>
<LI>
<tt>boost::array&lt;T,sz></tt>
<LI>
<tt>std::vector&lt;bool&gt;</tt>
</UL> </UL>
<h3>See also</h3> <h3>See also</h3> <A href="http://www.sgi.com/Technology/STL/Container.html">Container</A>
<A href="http://www.sgi.com/Technology/STL/Container.html">Container</A>
<br><br> <br>
<br>
<hr> <hr>
<br> <br>
<a name=reversible_range> <a name=reversible_range><h1>ReversibleRange</h1>
<h1>ReversibleRange</h1>
<h3>Description</h3> <h3>Description</h3> This concept provides access to iterators that traverse in
This concept provides access to iterators that traverse in both both directions (forward and reverse). The iterator type must meet all of the
directions (forward and reverse). The iterator type must meet all of requirements of <a
the requirements of <a href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">BidirectionalIterator</a>
href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">BidirectionalIterator</a> except that the reference type does not have to be a real C++ reference.
except that the reference type does not have to be a real C++
reference.
<h3>Refinement of</h3> <h3>Refinement of</h3> Range
Range
<h3>Associated types</h3> <h3>Associated types</h3>
<Table border> <Table border>
<TR> <TR>
<TD VAlign=top> <TD VAlign="top">Reverse Iterator type</TD>
Reverse Iterator type <TD VAlign="top"><tt>X::reverse_iterator</tt></TD>
</TD> <TD VAlign="top">The type of iterator used to iterate through a Range's elements
<TD VAlign=top> in reverse order. The iterator's value type is expected to be the Range's value
<tt>X::reverse_iterator</tt> type. A conversion from the reverse iterator type to the const reverse iterator
</TD> type must exist. The iterator type must at least be a <a
<TD VAlign=top> href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">BidirectionalIterator</a>.</TD>
The type of iterator used to iterate through a Range's </TR>
elements in reverse order. The iterator's value type is expected to be the <TR>
Range's value type. A conversion <TD VAlign="top">Const reverse iterator type</TD>
from the reverse iterator type to the const reverse iterator type must exist. <TD VAlign="top"><tt>X::const_reverse_iterator</tt></TD>
The iterator type must at least be a <a <TD VAlign="top">A type of reverse iterator that may be used to examine, but not
href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">BidirectionalIterator</a>. to modify, a Range's elements.</TD>
</TD> </TR>
</TR>
<TR>
<TD VAlign=top>
Const reverse iterator type
</TD>
<TD VAlign=top>
<tt>X::const_reverse_iterator</tt>
</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> </table>
<h3>Valid expressions</h3> <h3>Valid expressions</h3>
<Table border> <Table border>
<TR> <TR>
<TH> <TH>Name</TH>
Name <TH>Expression</TH>
</TH> <TH>Return type</TH>
<TH> <TH>Semantics</TH>
Expression </TR>
</TH> <TR>
<TH> <TD VAlign="top">Beginning of range</TD>
Return type <TD VAlign="top"><tt>rbegin(a)</tt></TD>
</TH> <TD VAlign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable, <tt>const_reverse_iterator</tt>
<TH> otherwise.</TD>
Semantics <TD VAlign="top">Equivalent to <tt>X::reverse_iterator(end(a))</tt>.</TD> </TR>
</TH> <TR>
</TR> <TD VAlign="top">End of range</TD>
<TR> <TD VAlign="top"><tt>rend(a)</tt></TD>
<TD VAlign=top> <TD VAlign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable, <tt>const_reverse_iterator</tt>
Beginning of range otherwise.</TD>
</TD> <TD VAlign="top">Equivalent to
<TD VAlign=top> <tt>X::reverse_iterator(begin(a))</tt>.</TD> </tr>
<tt>a.rbegin()</tt>
</TD>
<TD VAlign=top>
<tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
<tt>const_reverse_iterator</tt> otherwise.
</TD>
<TD VAlign=top>
Equivalent to <tt>X::reverse_iterator(a.end())</tt>.
</TD>
</TR>
<TR>
<TD VAlign=top>
End of range
</TD>
<TD VAlign=top>
<tt>a.rend()</tt>
</TD>
<TD VAlign=top>
<tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
<tt>const_reverse_iterator</tt> otherwise.
</TD>
<TD VAlign=top>
Equivalent to <tt>X::reverse_iterator(a.begin())</tt>.
</TD>
</tr>
</table> </table>
<h3>Complexity guarantees</h3> <h3>Complexity guarantees</h3>
<tt>rbegin()</tt> has the same complexity as <tt>end()</tt> and <tt>rbegin(a)</tt> has the same complexity as <tt>end(a)</tt> and
<tt>rend()</tt> has the same complexity as <tt>begin()</tt> from Range. <tt>rend(a)</tt> has the same complexity as <tt>begin(a)</tt> from Range.
<h3>Models</h3> <h3>Models</h3>
<ul> <ul>
<li> std::vector&lt;T> <li>
<li> std::list&lt;T> std::vector&lt;T>
<li>
std::list&lt;T>
</ul> </ul>
<hr> <hr>
<h3>Notes</h3> <h3>Notes</h3>
<P><A name="1">[1]</A> <P>
<A name="1">[1]</A>
The reference type does not have to be a real C++ reference. The The reference type does not have to be a real C++ reference. The requirements of
requirements of the reference type depend on the context within which the reference type is that it <i>behaves</i> like a real reference. Hence the
the Range is being used. Specifically it depends on the reference type must be convertible to the value_type and assignment through
requirements the context places on the value type of the Range.
The reference type of the Range must meet the same requirements
as the value type. In addition, the reference objects must be
equivalent to the value type objects in the Range (which is
trivially true if they are the same). Also, in a mutable Range,
an assignment to the reference object must result in an assignment to
the object in the Range (again, which is trivially true if they
are the same object, but non-trivial if the reference type is a proxy
class).
<br>
<br><br> <br>
<HR> <HR>
<br> <br>
<TABLE> <TABLE>
<TR valign=top> <TR valign="top">
<TD nowrap>Copyright &copy 2000</TD><TD> <TD nowrap>Copyright &copy 2000</TD>
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame and C++ Library & Compiler Group/SGI (<A HREF="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</A>) <TD><A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>
</TD></TR> </TR>
<tr > <tr >
<TD nowrap>Copyright &copy 2004</TD><TD> <TD nowrap>Copyright &copy 2004</TD>
Thorsten Ottosen. <TD>Thorsten Ottosen.
</TABLE> </TABLE>
</BODY> </BODY>
</HTML> </HTML>

View File

@@ -21,3 +21,11 @@ pre{
.preprocessor{color: #3F007F;} .preprocessor{color: #3F007F;}
.string{font-style: italic; color: #666666;} .string{font-style: italic; color: #666666;}
.literal{font-style: italic; color: #666666;} .literal{font-style: italic; color: #666666;}
table
{
cellpadding: 5px;
border: 2px;
}

View File

@@ -2,145 +2,122 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Range Terminology and Style Guidelines </title> <title>Boost.Range Terminology and Style Guidelines </title>
<link rel="stylesheet" href="style.css" type="text/css"> <link rel="stylesheet" href="style.css" type="text/css">
</head> </head>
<body> <body>
<table border="0" > <table border="0" >
<tr> <tr>
<td ><img src="cboost.gif" border="0" ></td> <td ><img src="cboost.gif" border="0" ></td>
<td > <td ><h1 align="center">Boost.Range </h1></td> </tr>
<h1 align="center">Boost.Range terminology and style guidelines</h1> </table>
</td>
</tr> <h2>Terminology and style guidelines </h2>
</table>
<p>
<p> The use of a consistent terminologi is as important for iterator <a href="range.html#range">Range</a>s
The use of a consistent terminologi is as important for and <a href="range.html#external_range">ExternalRange</a>-based algorithms as it
iterator <a href="range.html#range">Range</a>s and is for iterators and iterator-based algorithms. If a conventional set of names
<a href="range.html#external_range">ExternalRange</a>-based algorithms are adopted, we can avoid misunderstandings and write generic function
as it is for iterators and iterator-based algorithms. prototypes that are <i>self-documenting</i>.
If a conventional set of names are adopted, we can avoid misunderstandings </p>
and write generic function prototypes that are <i>self-documenting</i>.
</p> <p>
Since iterator ranges are characterized by a specific underlying iterator type,
<p> we get a type of iterator range for each type of iterator. Hence we can speak of
Since iterator ranges are characterized by a specific underlying the following types of iterator ranges:
iterator type, we get a type of iterator range for each type of <ul>
iterator. Hence we can speak of the following types of iterator <li>
ranges: Range
<ul> <li>
<li> Range ReversibleRange
<li> ReversibleRange <li>
<li> <i>Value access</i> category: <i>Value access</i> category:
<ul> <ul>
<li> ReadableRange <li>
<li> WriteableRange ReadableRange
<li> SwappableRange <li>
<li> LvalueRange WriteableRange
</ul> <li>
<li> <i>Traversal</i> category: SwappableRange
<ul> <li>
<li> IncrementableRange LvalueRange
<li> SinglePassRange </ul>
<li> ForwardRange <li>
<li> BidirectionalRange <i>Traversal</i> category:
<li> RandomAccessRange <ul>
</ul> <li>
</ul> IncrementableRange
Notice how we have used the categories from the <li>
<a href=../../iterator/doc/new-iter-concepts.html>new style iterators</a>. SinglePassRange
Similarly, for <a href="range.html#external_range">ExternalRange</a> <li>
we have ForwardRange
<ul> <li>
<li> XRange BidirectionalRange
<li> XReversibleRange <li>
<li> <i>Value access</i> category: RandomAccessRange
<ul> </ul>
<li> XReadableRange </ul>
<li> XWriteableRange Notice how we have used the categories from the <a href=../../iterator/doc/new-iter-concepts.html>new
<li> XSwappableRange style iterators</a>.
<li> XLvalueRange
</ul> <p>
<li> <i>Traversal</i> category: Notice that an interator (and therefore an iterator range) has one <i>traversal</i>
<ul> property and one or more properties from the <i>value access</i> category. So in
<li> XIncrementableRange reality we will mostly talk about mixtures such as
<li> XSinglePassRange <ul>
<li> XForwardRange <li>
<li> XBidirectionalRange RandomAccessReadableWriteableRange
<li> XRandomAccessRange <li>
</ul> ForwardLvalueRange
</ul> </ul>
The convention of using an <code>X</code> to mean "External" save us from By convention, we should always specify the <i>travelsal</i> property first as
rediculously long parameter names and is easy to associate with an done above. This seems resonable since there will only be one <i>traversal</i>
<a href=external_concepts.html>external concept</a>. property, but perhaps many <i>value acccess</i> properties.
</p>
<p>
Notice that an interator (and therefore an iterator range) has <p>
one <i>traversal</i> property and one or more properties from the As an example, consider how we specify the interface of <code>std::sort()</code>.
<i>value access</i> category. So in reality we will mostly talk about The iterator-based version looks like this:
mixtures such as <ul> <li>RandomAccessReadableWriteableRange
<li>XForwardLvalueRange <pre>
</ul>
By convention, we should always specify the <i>travelsal</i> property first
as done above. This seems resonable since there will only be one
<i>traversal</i> property, but perhaps many <i>value acccess</i> properties.
</p>
<p>
As an example, consider how we specify the interface of
<code>std::sort()</code>. The iterator-based version looks like
this:
<pre>
template< class RandomAccessTraversalReadableWritableIterator > template< class RandomAccessTraversalReadableWritableIterator >
void sort( RandomAccessTraversalReadableWritableIterator first, void sort( RandomAccessTraversalReadableWritableIterator first,
RandomAccessTraversalReadableWritableIterator last ); RandomAccessTraversalReadableWritableIterator last );
</pre> </pre>
For external iterator ranges the interface becomes For iterator ranges the interface becomes
<pre> <pre>
template< class XRandomAccessReadableWritableRange >
void sort( XRandomAccessReadableWritableRange& r );
</pre>
Had the function been specified like
<pre>
template< class RandomAccessReadableWritableRange > template< class RandomAccessReadableWritableRange >
void sort( RandomAccessReadableWritableRange& r ); void sort( RandomAccessReadableWritableRange& r );
</pre> </pre>
we should expect the underlying code to call <code>r.begin()</code>
and <code>r.end()</code> to extract the iterators instead of </p>
<code>begin( r )</code> and <code>end( r )</code>. In general
it is much more flexible to rely on external iterator ranges
than iterator ranges. <hr>
</p> <p>
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004 (C) Copyright Thorsten Ottosen 2003-2004
</p> </p>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
<br> <br>
</body> </body>
</html> </html>

View File

@@ -34,18 +34,15 @@
</p> </p>
<ul> <ul>
<li> Introduction <li> <a href=doc/intro.html>Introduction </a></code>
<li> Concepts: <li> <a href=doc/range.htm>Concepts:</a>
<ul> <ul>
<li> <a href="doc/range.htm#range">Range</a> <li> <a href="doc/range.htm#range">Range</a>
<li> <a href="doc/range.htm#reversible_range">ReversibleRange</a> <li> <a href="doc/range.htm#reversible_range">ReversibleRange</a>
<li> ExternalRange
<li> ExternalReversibleRange
</ul> </ul>
<li> <a href=doc/boost_range.html>Implementation</a> of ExternalReversibleRange for <li> <a href=doc/boost_range.html>Implementation</a> of Range and ReversibleRange for <ul>
<ul>
<li> arrays <li> arrays
<li> Ranges <li> Ranges
<li> strings <li> strings
@@ -58,7 +55,10 @@
<li> Class <a href="doc/utility_class.html#sub_range"><code>sub_range</code></a> </ul> <li> Class <a href="doc/utility_class.html#sub_range"><code>sub_range</code></a> </ul>
<li> <a href=doc/style.html>Terminology and style guidelines </a> <li> <a href=doc/style.html>Terminology and style guidelines </a>
<li><a href="#headers">Headers</a> </li> <li><a href="doc/headers.html">Headers</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> </ul>