Files
boost_range/doc/intro.html
Thorsten Jørgen Ottosen 8378643b44 *** empty log message ***
[SVN r24430]
2004-08-12 10:58:13 +00:00

163 lines
14 KiB
HTML
Executable File

<!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>
When writing generic code that works with standard library containers, one
often finds it desirable to extend that code to work with other types that offer
enough functionality to satisfy the needs of the generic code, but in an altered
form. For example, raw arrays are often suitable for use with generic code that
works with containers, provided a suitable adapter is used. Likewise, null
terminated strings can be treated as containers of characters, if suitably
adapted.
</p>
<p>
This library provides the means to adapt standard library
containers,
null terminated strings, <code>std::pairs</code> of iterators, and raw
arrays (and more), such that the same generic code can work with them all.
The basic idea is to add another layer of indirection using <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a> and
free-standing functions so syntactic and/or semantic differences can be removed.
</p>
<!-- <p>
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 >
simpler implementation of generic range algorithms
</li>
<li >
more flexible client code
</li>
<li >
correct handling of null-terminated strings
</li>
<li >
safe use of built-in arrays (for legacy code; why else would you use
arrays?) </li>
</ul>
</p>
<p >
Below are given a small example (the complete example can be found <a href="../test/algorithm_example.cpp" target="_self" >here</a>
):
<blockquote>
<pre >
<span class=comment>
//
// example: extracting bounds in a generic algorithm
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>ForwardReadableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>const_iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>find</span><span class=special>( </span><span class=keyword>const </span><span class=identifier>ForwardReadableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>find</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>value </span><span class=special>);
</span><span class=special>}
</span><span class=comment>//
// replace first value and return its index
//
</span><span class=keyword>template</span><span class=special>&lt; </span><span class=keyword>class </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>, </span><span class=keyword>class </span><span class=identifier>T </span><span class=special>&gt;
</span><span class=keyword>inline </span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>size_type_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type
</span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>ForwardReadableWriteableRange</span><span class=special>&amp; </span><span class=identifier>c</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>value</span><span class=special>, </span><span class=keyword>const </span><span class=identifier>T</span><span class=special>&amp; </span><span class=identifier>replacement </span><span class=special>)
</span><span class=special>{
</span><span class=keyword>typename </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>iterator_of</span><span class=special>&lt; </span><span class=identifier>ForwardReadableWriteableRange </span><span class=special>&gt;::</span><span class=identifier>type </span><span class=identifier>found </span><span class=special>= </span><span class=identifier>find</span><span class=special>( </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>value </span><span class=special>);
</span><span class=keyword>if</span><span class=special>( </span><span class=identifier>found </span><span class=special>!= </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>c </span><span class=special>) </span><span class=special>)
</span><span class=special>*</span><span class=identifier>found </span><span class=special>= </span><span class=identifier>replacement</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>distance</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>c </span><span class=special>), </span><span class=identifier>found </span><span class=special>);
</span><span class=special>}
</span><span class=comment>//
// usage
//
</span><span class=keyword>const </span><span class=keyword>int </span><span class=identifier>N </span><span class=special>= </span><span class=number>5</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=identifier>my_vector</span><span class=special>;
</span><span class=keyword>int </span><span class=identifier>values</span><span class=special>[] </span><span class=special>= </span><span class=special>{ </span><span class=number>1</span><span class=special>,</span><span class=number>2</span><span class=special>,</span><span class=number>3</span><span class=special>,</span><span class=number>4</span><span class=special>,</span><span class=number>5</span><span class=special>,</span><span class=number>6</span><span class=special>,</span><span class=number>7</span><span class=special>,</span><span class=number>8</span><span class=special>,</span><span class=number>9 </span><span class=special>};
</span>
<span class=identifier>my_vector</span><span class=special>.</span><span
class=identifier>assign</span><span class=special>( </span><span class=identifier>values</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>end</span><span class=special>( </span><span class=identifier>values </span><span class=special>) </span><span class=special>);</span>
</span><span class=keyword>typedef </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;::</span><span class=identifier>iterator </span><span class=identifier>iterator</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=identifier>iterator</span><span class=special>&gt; </span><span class=identifier>my_view</span><span class=special>( </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>),
</span><span
class=identifier>boost</span><span
class=special>::</span><span class=identifier>begin</span><span class=special>( </span><span class=identifier>my_vector </span><span class=special>) </span><span class=special>+ </span><span class=identifier>N </span><span class=special>);
</span><span class=keyword>char </span><span class=identifier>str_val</span><span class=special>[] </span><span class=special>= </span><span class=string>&quot;a string&quot;</span><span class=special>;
</span><span class=keyword>char</span><span class=special>* </span><span class=identifier>str </span><span class=special>= </span><span class=identifier>str_val</span><span class=special>;
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_vector</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>my_view</span><span class=special>, </span><span class=number>4</span><span class=special>, </span><span class=number>2 </span><span class=special>)
</span><span class=special>&lt;&lt; </span><span class=identifier>my_generic_replace</span><span class=special>( </span><span class=identifier>str</span><span class=special>, </span><span class=literal>'a'</span><span class=special>, </span><span class=literal>'b' </span><span class=special>);
</span>
<span class=comment>// prints '3', '5' and '0' </span>
</pre>
</blockquote>
By using the free-standing functions and <a
href="../../mpl/doc/index.html#metafunctions">metafunctions</a>, the code automatically
works for all the types supported by this library; now and in the future.
Notice that we have to
provide two version of <code >find()</code> since we cannot forward a non-const
rvalue with reference arguments (see this article about <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_self" >The
Forwarding Problem</a> ).
</p>
<hr>
<p>
(C) Copyright Thorsten Ottosen 2003-2004
</p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</body>
</html>