Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/multi_index/doc/examples.html @ 13

Last change on this file since 13 was 12, checked in by landauf, 18 years ago

added boost

File size: 16.5 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
2
3<html>
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
6<title>Boost.MultiIndex Documentation - Examples</title>
7<link rel="stylesheet" href="style.css" type="text/css">
8</head>
9
10<body>
11<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" align=
12"middle" width="277" height="86">Boost.MultiIndex Examples</h1>
13
14<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
15Performance
16</a></div>
17<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
18Index
19</a></div>
20<div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br>
21Tests
22</a></div><br clear="all" style="clear: all;">
23
24<hr>
25
26<h2>Contents</h2>
27
28<ul>
29  <li><a href="#example1">Example 1: basic usage</a></li>
30  <li><a href="#example2">Example 2: using member functions as keys</a></li>
31  <li><a href="#example3">Example 3: constructing <code>multi_index_container</code>s
32    with <code>ctor_args_list</code></a></li>
33  <li><a href="#example4">Example 4: bidirectional map</a></li>
34  <li><a href="#example5">Example 5: sequenced indices</a></li>
35  <li><a href="#example6">Example 6: complex searches and foreign keys</a></li>
36  <li><a href="#example7">Example 7: composite keys</a></li>
37  <li><a href="#example8">Example 8: hashed indices</a></li>
38  <li><a href="#example9">Example 9: serialization and MRU lists</a></li>
39</ul>
40
41<h2><a name="example1">Example 1: basic usage</a></h2>
42
43<p>
44See <a href="../example/basic.cpp">source code</a>.
45</p>
46
47<p>
48Basic program showing the multi-indexing capabilities of Boost.MultiIndex
49with an admittedly boring set of <code>employee</code> records.
50</p>
51
52<h2><a name="example2">Example 2: using member functions as keys</a></h2>
53
54<p>
55See <a href="../example/memfun_key.cpp">source code</a>.
56</p>
57
58<p>
59Usually keys assigned to an index are based on a member variable of the
60element, but key extractors can be defined which take their value from
61a member function. This has some similarity with the concept of
62<i>calculated keys</i> supported by some relational database engines.
63The example shows how to use the predefined <code>const_mem_fun</code>
64key extractor to deal with this situation.
65</p>
66
67<p>
68Keys based on member functions usually will not be actual references,
69but rather the temporary values resulting from the invocation of the
70member function used. This implies that <code>modify_key</code> cannot be
71applied to this type of extractors, which is a perfectly logical
72constraint anyway.
73</p>
74
75<h2><a name="example3">Example 3: constructing <code>multi_index_container</code>s
76with <code>ctor_args_list</code></a></h2>
77
78<p>
79See <a href="../example/non_default_ctor.cpp">source code</a>.
80</p>
81
82<p>
83We show a practical example of usage of <code>multi_index_container::ctor_arg_list</code>,
84whose definition and purpose are explained in the
85<a href="advanced_topics.html#ctor_args_list">Advanced topics section</a>. The
86program groups a sorted collection of numbers based on identification through
87modulo arithmetics, by which <code>x</code> and <code>y</code> are equivalent
88if <code>(x%n)==(y%n)</code>, for some fixed <code>n</code>.
89</p>
90
91<h2><a name="example4">Example 4: bidirectional map</a></h2>
92
93<p>
94See <a href="../example/bimap.cpp">source code</a>.
95</p>
96
97<p>
98This example shows how to construct a bidirectional map with
99<code>multi_index_container</code>. By a <i>bidirectional map</i> we mean
100a container of elements of <code>std::pair&lt;const FromType,const ToType></code>
101such that no two elements exists with the same <code>first</code>
102<i>or</i> <code>second</code> value (<code>std::map</code> only
103guarantees uniqueness of the first member). Fast lookup is provided
104for both keys. The program features a tiny Spanish-English
105dictionary with online query of words in both languages.
106</p>
107
108<h2><a name="example5">Example 5: sequenced indices</a></h2>
109
110<p>
111See <a href="../example/sequenced.cpp">source code</a>.
112</p>
113
114<p>
115The combination of a sequenced index with an index of type <code>ordered_non_unique</code>
116yields a <code>list</code>-like structure with fast lookup capabilities. The
117example performs some operations on a given text, like word counting and
118selective deletion of some words.
119</p>
120
121<h2><a name="example6">Example 6: complex searches and foreign keys</a></h2>
122
123<p>
124See <a href="../example/complex_structs.cpp">source code</a>.
125</p>
126
127<p>
128This program illustrates some advanced techniques that can be applied
129for complex data structures using <code>multi_index_container</code>.
130Consider a <code>car_model</code> class for storing information
131about automobiles. On a first approach, <code>car_model</code> can
132be defined as:
133</p>
134
135<blockquote><pre>
136<span class=keyword>struct</span> <span class=identifier>car_model</span>
137<span class=special>{</span>
138  <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>model</span><span class=special>;</span>
139  <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>manufacturer</span><span class=special>;</span>
140  <span class=keyword>int</span>         <span class=identifier>price</span><span class=special>;</span>
141<span class=special>};</span>
142</pre></blockquote>
143
144<p>
145This definition has a design flaw that any reader acquainted with
146relational databases can easily spot: The <code>manufacturer</code>
147member is duplicated among all cars having the same manufacturer.
148This is a waste of space and poses difficulties when, for instance,
149the name of a manufacturer has to be changed. Following the usual
150principles in relational database design, the appropriate design
151involves having the manufactures stored in a separate
152<code>multi_index_container</code> and store pointers to these in
153<code>car_model</code>:
154</p>
155
156<blockquote><pre>
157<span class=keyword>struct</span> <span class=identifier>car_manufacturer</span>
158<span class=special>{</span>
159  <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span> <span class=identifier>name</span><span class=special>;</span>
160<span class=special>};</span>
161
162<span class=keyword>struct</span> <span class=identifier>car_model</span>
163<span class=special>{</span>
164  <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span>       <span class=identifier>model</span><span class=special>;</span>
165  <span class=identifier>car_manufacturer</span><span class=special>*</span> <span class=identifier>manufacturer</span><span class=special>;</span>
166  <span class=keyword>int</span>               <span class=identifier>price</span><span class=special>;</span>
167<span class=special>};</span>
168</pre></blockquote>
169
170<p>
171Although predefined Boost.MultiIndex key extractors can handle many
172situations involving pointers (see
173<a href="advanced_topics.html#advanced_key_extractors">advanced features
174of Boost.MultiIndex key extractors</a> in the Advanced topics section), this case
175is complex enough that a suitable key extractor has to be defined. The following
176utility cascades two key extractors:
177</p>
178
179<blockquote><pre>
180<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>KeyExtractor1</span><span class=special>,</span><span class=keyword>class</span> <span class=identifier>KeyExtractor2</span><span class=special>&gt;</span>
181<span class=keyword>struct</span> <span class=identifier>key_from_key</span>
182<span class=special>{</span>
183<span class=keyword>public</span><span class=special>:</span>
184  <span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>KeyExtractor1</span><span class=special>::</span><span class=identifier>result_type</span> <span class=identifier>result_type</span><span class=special>;</span>
185
186  <span class=identifier>key_from_key</span><span class=special>(</span>
187    <span class=keyword>const</span> <span class=identifier>KeyExtractor1</span><span class=special>&amp;</span> <span class=identifier>key1_</span><span class=special>=</span><span class=identifier>KeyExtractor1</span><span class=special>(),</span>
188    <span class=keyword>const</span> <span class=identifier>KeyExtractor2</span><span class=special>&amp;</span> <span class=identifier>key2_</span><span class=special>=</span><span class=identifier>KeyExtractor2</span><span class=special>()):</span>
189    <span class=identifier>key1</span><span class=special>(</span><span class=identifier>key1_</span><span class=special>),</span><span class=identifier>key2</span><span class=special>(</span><span class=identifier>key2_</span><span class=special>)</span>
190  <span class=special>{}</span>
191
192  <span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Arg</span><span class=special>&gt;</span>
193  <span class=identifier>result_type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Arg</span><span class=special>&amp;</span> <span class=identifier>arg</span><span class=special>)</span><span class=keyword>const</span>
194  <span class=special>{</span>
195    <span class=keyword>return</span> <span class=identifier>key1</span><span class=special>(</span><span class=identifier>key2</span><span class=special>(</span><span class=identifier>arg</span><span class=special>));</span>
196  <span class=special>}</span>
197
198<span class=keyword>private</span><span class=special>:</span>
199  <span class=identifier>KeyExtractor1</span> <span class=identifier>key1</span><span class=special>;</span>
200  <span class=identifier>KeyExtractor2</span> <span class=identifier>key2</span><span class=special>;</span>
201<span class=special>};</span>
202</pre></blockquote>
203
204<p>
205so that access from a <code>car_model</code> to the <code>name</code> field
206of its associated <code>car_manufacturer</code> can be accomplished with
207</p>
208
209<blockquote><pre>
210<span class=identifier>key_from_key</span><span class=special>&lt;</span>
211  <span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>car_manufacturer</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>,&amp;</span><span class=identifier>car_manufacturer</span><span class=special>::</span><span class=identifier>name</span><span class=special>&gt;,</span>
212  <span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>car_model</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>car_manufacturer</span> <span class=special>*,</span><span class=identifier>car_model</span><span class=special>::</span><span class=identifier>manufacturer</span><span class=special>&gt;</span>
213<span class=special>&gt;</span>
214</pre></blockquote>
215
216<p>
217The program asks the user for a car manufacturer and a range of prices
218and returns the car models satisfying these requirements. This is a complex
219search that cannot be performed on a single operation. Broadly sketched,
220one procedure for executing the selection is:
221<ol>
222  <li>Select the elements with the given manufacturer by means
223    of <code>equal_range</code>,
224  <li>feed these elements into a <code>multi_index_container</code> sorted
225    by price,
226  <li>select by price using <code>lower_bound</code> and
227    <code>upper_bound</code>;
228</ol>
229or alternatively:
230<ol>
231  <li>Select the elements within the price range with
232  <code>lower_bound</code> and <code>upper_bound</code>,
233  <li>feed these elements into a <code>multi_index_container</code> sorted
234    by manufacturer,
235  <li>locate the elements with given manufacturer using
236    <code>equal_range</code>.
237</ol>
238An interesting technique developed in the example lies in
239the construction of the intermediate <code>multi_index_container</code>.
240In order to avoid object copying, appropriate <i>view</i> types
241are defined with <code>multi_index_container</code>s having as elements
242pointers to <code>car_model</code>s instead of actual objects.
243These views have to be supplemented with appropriate
244dereferencing key extractors.
245</p>
246
247<h2><a name="example7">Example 7: composite keys</a></h2>
248
249<p>
250See <a href="../example/composite_keys.cpp">source code</a>.
251</p>
252
253<p>
254Boost.MultiIndex <a href="advanced_topics.html#composite_keys">
255<code>composite_key</code></a> construct provides a flexible tool for
256creating indices with non-trivial sorting criteria.
257The program features a rudimentary simulation of a file system
258along with an interactive Unix-like shell. A file entry is represented by
259the following structure:
260</p>
261
262<blockquote><pre>
263<span class=keyword>struct</span> <span class=identifier>file_entry</span>
264<span class=special>{</span>
265  <span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span>       <span class=identifier>name</span><span class=special>;</span>
266  <span class=keyword>unsigned</span>          <span class=identifier>size</span><span class=special>;</span>
267  <span class=keyword>bool</span>              <span class=identifier>is_dir</span><span class=special>;</span> <span class=comment>// true if the entry is a directory</span>
268  <span class=keyword>const</span> <span class=identifier>file_entry</span><span class=special>*</span> <span class=identifier>dir</span><span class=special>;</span>    <span class=comment>// directory this entry belongs in</span>
269<span class=special>};</span>
270</pre></blockquote>
271
272<p>
273Entries are kept in a <code>multi_index_container</code> maintaining two indices
274with composite keys:
275<ul>
276  <li>A primary index ordered by directory and name,</li>
277  <li>a secondary index ordered by directory and size.</li>
278</ul>
279The reason that the order is made firstly by the directory in which
280the files are located obeys to the local nature of the shell commands,
281like for instance <code>ls</code>. The shell simulation only has three
282commands:
283<ul>
284  <li><code>cd [.|..|<i>&lt;directory&gt;</i>]</code></li>
285  <li><code>ls [-s]</code> (<code>-s</code> orders the output by size)</li>
286  <li><code>mkdir <i>&lt;directory&gt;</i></code></li>
287</ul>
288The program exits when the user presses the Enter key at the command prompt.
289</p>
290
291<p>
292The reader is challenged to add more functionality to the program; for
293instance:
294<ul>
295  <li>Implement additional commands, like <code>cp</code>.</li>
296  <li>Add handling of absolute paths.</li>
297  <li>Use <a href="advanced_topics.html#serialization">serialization</a>
298    to store and retrieve the filesystem state between program runs.</li>
299</ul>
300</p>
301
302<h2><a name="example8">Example 8: hashed indices</a></h2>
303
304<p>
305See <a href="../example/hashed.cpp">source code</a>.
306</p>
307
308<p>
309Hashed indices can be used as an alternative to ordered indices when
310fast lookup is needed and sorting information is of no interest. The
311example features a word counter where duplicate entries are checked
312by means of a hashed index. Confront the word counting algorithm with
313that of <a href="#example5">example 5</a>.
314</p>
315
316<h2><a name="example9">Example 9: serialization and MRU lists</a></h2>
317
318<p>
319See <a href="../example/serialization.cpp">source code</a>.
320</p>
321
322<p>
323A typical application of serialization capabilities allows a program to
324restore the user context between executions. The example program asks
325the user for words and keeps a record of the ten most recently entered
326ones, in the current or in previous sessions. The serialized data structure,
327sometimes called an <i>MRU (most recently used) list</i>, has some interest
328on its own: an MRU list behaves as a regular FIFO queue, with the exception
329that, when inserting a preexistent entry, this does not appear twice, but
330instead the entry is moved to the front of the list. You can observe this
331behavior in many programs featuring a "Recent files" menu command. This
332data structure is implemented with <code>multi_index_container</code> by
333combining a sequenced index and an index of type <code>hashed_unique</code>.
334</p>
335
336<hr>
337
338<div class="prev_link"><a href="performance.html"><img src="prev.gif" alt="performance" border="0"><br>
339Performance
340</a></div>
341<div class="up_link"><a href="index.html"><img src="up.gif" alt="index" border="0"><br>
342Index
343</a></div>
344<div class="next_link"><a href="tests.html"><img src="next.gif" alt="tests" border="0"><br>
345Tests
346</a></div><br clear="all" style="clear: all;">
347
348<br>
349
350<p>Revised August 22nd 2005</p>
351
352<p>&copy; Copyright 2003-2005 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
353Distributed under the Boost Software
354License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
355LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
356http://www.boost.org/LICENSE_1_0.txt</a>)
357</p>
358
359</body>
360</html>
Note: See TracBrowser for help on using the repository browser.