blob: 0a0213873160685319f483b9372f2acc5a411954 [file] [log] [blame]
Brian Silverman3cbbaca2018-08-04 23:38:07 -07001<!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 - Tutorial - Container creation</title>
7<link rel="stylesheet" href="../style.css" type="text/css">
8<link rel="start" href="../index.html">
9<link rel="prev" href="key_extraction.html">
10<link rel="up" href="index.html">
11<link rel="next" href="debug.html">
12</head>
13
14<body>
15<h1><img src="../../../../boost.png" alt="boost.png (6897 bytes)" align=
16"middle" width="277" height="86">Boost.MultiIndex Tutorial: Container creation</h1>
17
18<div class="prev_link"><a href="key_extraction.html"><img src="../prev.gif" alt="key extraction" border="0"><br>
19Key extraction
20</a></div>
21<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
22Boost.MultiIndex tutorial
23</a></div>
24<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
25Debugging support
26</a></div><br clear="all" style="clear: all;">
27
28<hr>
29
30<h2>Contents</h2>
31
32<ul>
33 <li><a href="#value_semantics">Value semantics</a></li>
34 <li><a href="#ctor_args_list">Use of <code>ctor_args_list</code></a></li>
35 <li><a href="#special_allocator">Special allocator support</a></li>
36 <li><a href="#serialization">Serialization</a></li>
37</ul>
38
39<h2><a name="value_semantics">Value semantics</a></h2>
40
41<p>
42<code>multi_index_container</code>s have the usual value semantics associated
43to copy construction and assignment, i.e. copies of the elements from the source
44container are created and inserted into the destination container.
45More interestingly, copying also recreates the original order in which
46elements are arranged for <i>every index</i> of the container.
47This implies that equality of all indices is preserved under copying
48or assignment, for those index types where equality is defined. This behavior
49can be regarded as a natural extension to the general rule on copy semantics
50stating that if <code>y</code> is a copy of <code>x</code>, then
51<code>y==x</code>.
52</p>
53
54<h2><a name="ctor_args_list">Use of <code>ctor_args_list</code></a></h2>
55
56<p>
57Although in most cases <code>multi_index_container</code>s will be default constructed
58(or copied from a preexisting <code>multi_index_container</code>), sometimes it is
59necessary to specify particular values for the internal objects used (key extractors,
60comparison predicates, allocator), for instance if some of these objects do not have
61a default constructor. The same situation can arise with standard STL containers,
62which allow for the optional specification of such objects:
63</p>
64
65<blockquote><pre>
66<span class=comment>// example of non-default constructed std::set</span>
67<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>IntegralType</span><span class=special>&gt;</span>
68<span class=keyword>struct</span> <span class=identifier>modulo_less</span>
69<span class=special>{</span>
70 <span class=identifier>modulo_less</span><span class=special>(</span><span class=identifier>IntegralType</span> <span class=identifier>m</span><span class=special>):</span><span class=identifier>modulo</span><span class=special>(</span><span class=identifier>m</span><span class=special>){}</span>
71
72 <span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>IntegralType</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>IntegralType</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span>
73 <span class=special>{</span>
74 <span class=keyword>return</span> <span class=special>(</span><span class=identifier>x</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>)&lt;(</span><span class=identifier>y</span><span class=special>%</span><span class=identifier>modulo</span><span class=special>);</span>
75 <span class=special>}</span>
76
77<span class=keyword>private</span><span class=special>:</span>
78 <span class=identifier>IntegralType</span> <span class=identifier>modulo</span><span class=special>;</span>
79<span class=special>};</span>
80
81<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>modulo_set</span><span class=special>;</span>
82
83<span class=identifier>modulo_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(</span><span class=number>10</span><span class=special>));</span>
84</pre></blockquote>
85
86<p>
87<code>multi_index_container</code> does also provide this functionality, though in a
88considerably more complex fashion, due to the fact that the constructor
89of a <code>multi_index_container</code> has to accept values for all the internal
90objects of its indices. The full form of <code>multi_index_container</code> constructor
91is
92</p>
93
94<blockquote><pre>
95<span class=keyword>explicit</span> <span class=identifier>multi_index_container</span><span class=special>(</span>
96 <span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
97 <span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
98</pre></blockquote>
99
100<p>
101The specification of the allocator object poses no particular problems;
102as for the <code>ctor_args_list</code>, this object is designed so as to hold
103the necessary construction values for every index in the <code>multi_index_container</code>.
104From the point of view of the user, <code>ctor_args_list</code> is equivalent
105to the type
106</p>
107
108<blockquote><pre>
109<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>C<sub>0</sub></span><span class=special>,...,</span><span class=identifier>C<sub>I-1</sub></span><span class=special>&gt;</span>
110</pre></blockquote>
111
112<p>
113where <code>I</code> is the number of indices, and <code>C<sub>i</sub></code> is
114</p>
115
116<blockquote><pre>
117<span class=identifier>nth_index</span><span class=special>&lt;</span><span class=identifier>i</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span>
118</pre></blockquote>
119
120<p>
121that is, the nested type <code>ctor_args</code> of the <code>i</code>-th index. Each
122<code>ctor_args</code> type is in turn a tuple holding values for constructor
123arguments of the associated index: so, ordered indices demand a key extractor object
124and a comparison predicate, hashed indices take an initial number of buckets,
125a key extractor, a hash function and an equality predicate; while sequenced
126and random access indices do not need any construction argument. For instance,
127given the definition
128</p>
129
130<blockquote><pre>
131<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
132 <span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span>
133 <span class=identifier>indexed_by</span><span class=special>&lt;</span>
134 <span class=identifier>hashed_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
135 <span class=identifier>ordered_non_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span> <span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
136 <span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
137 <span class=identifier>random_access</span><span class=special>&lt;&gt;</span>
138 <span class=special>&gt;</span>
139<span class=special>&gt;</span> <span class=identifier>modulo_indexed_set</span><span class=special>;</span>
140</pre></blockquote>
141
142<p>
143the corresponding <code>ctor_args_list</code> type is equivalent to
144</p>
145
146<blockquote><pre>
147<span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
148 <span class=comment>// ctr_args of index #0</span>
149 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
150 <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span><span class=special>,</span> <span class=comment>// initial number of buckets; 0 if unspecified</span>
151 <span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
152 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
153 <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
154
155 <span class=comment>// ctr_args of index #1</span>
156 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;</span>
157 <span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;,</span>
158 <span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;,</span>
159
160 <span class=comment>// sequenced indices do not have any construction argument</span>
161 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;&gt;,</span>
162
163 <span class=comment>// neither do random access indices</span>
164 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>tuple</span><span class=special>&lt;&gt;</span>
165<span class=special>&gt;</span>
166</pre></blockquote>
167
168<p>
169Such a <code>modulo_indexed_set</code> cannot be default constructed, because
170<code>modulo_less</code> does not provide a default constructor. The following shows
171how the construction can be done:
172</p>
173
174<blockquote><pre>
175<span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>ctor_args_list</span> <span class=identifier>args_list</span><span class=special>=</span>
176 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span>
177 <span class=comment>// ctor_args for index #0 is default constructible</span>
178 <span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>0</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
179
180 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>make_tuple</span><span class=special>(</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(),</span><span class=identifier>modulo_less</span><span class=special>&lt;</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>&gt;(</span><span class=number>10</span><span class=special>)),</span>
181
182 <span class=comment>// these are also default constructible (actually, empty tuples)</span>
183 <span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>2</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>(),</span>
184 <span class=identifier>modulo_indexed_set</span><span class=special>::</span><span class=identifier>nth_index</span><span class=special>&lt;</span><span class=number>3</span><span class=special>&gt;::</span><span class=identifier>type</span><span class=special>::</span><span class=identifier>ctor_args</span><span class=special>()</span>
185 <span class=special>);</span>
186
187<span class=identifier>modulo_indexed_set</span> <span class=identifier>m</span><span class=special>(</span><span class=identifier>args_list</span><span class=special>);</span>
188</pre></blockquote>
189
190<p>
191A program is provided in the <a href="../examples.html#example3">examples section</a> that
192puts in practise these concepts.
193</p>
194
195<h2><a name="special_allocator">Special allocator support</a></h2>
196
197<p>
198Boost.MultiIndex allows for a slightly more general class of allocators
199than strictly required by the C++ standard, as explained in detail in the
200<a href="../reference/multi_index_container.html#instantiation_types">reference</a>.
201An important type of non-standard allocators supported are those provided by the
202<a href="../../../interprocess/index.html">Boost Interprocess Library</a>;
203this opens up the possibility of placing <code>multi_index_container</code>s
204in shared memory.
205</p>
206
207<blockquote><pre>
208<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>allocators</span><span class=special>/</span><span class=identifier>allocator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
209<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>interprocess</span><span class=special>/</span><span class=identifier>managed_shared_memory</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
210
211<span class=keyword>namespace</span> <span class=identifier>bip</span><span class=special>=</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>interprocess</span><span class=special>;</span>
212
213<span class=comment>// a shared memory compatible allocator of ints</span>
214<span class=keyword>typedef</span> <span class=identifier>bip</span><span class=special>::</span><span class=identifier>allocator</span><span class=special>&lt;</span>
215 <span class=keyword>int</span><span class=special>,</span><span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span><span class=special>::</span><span class=identifier>segment_manager</span>
216<span class=special>&gt;</span> <span class=identifier>shared_int_allocator</span><span class=special>;</span>
217
218<span class=comment>// define a shared memory compatible multi_index_container
219// using shared_int_allocator</span>
220<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span>
221 <span class=keyword>int</span><span class=special>,</span>
222 <span class=identifier>indexed_by</span><span class=special>&lt;</span>
223 <span class=identifier>sequenced</span><span class=special>&lt;&gt;,</span>
224 <span class=identifier>ordered_unique</span><span class=special>&lt;</span><span class=identifier>identity</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span>
225 <span class=special>&gt;,</span>
226 <span class=identifier>shared_int_allocator</span>
227<span class=special>&gt;</span> <span class=identifier>unique_int_list</span><span class=special>;</span>
228
229<span class=special>...</span>
230
231<span class=comment>// create a managed memory segment</span>
232<span class=identifier>bip</span><span class=special>::</span><span class=identifier>managed_shared_memory</span> <span class=identifier>seg</span><span class=special>(</span>
233 <span class=identifier>bip</span><span class=special>::</span><span class=identifier>create_only</span><span class=special>,</span><span class=string>&quot;SharedMemoryID&quot;</span><span class=special>,</span><span class=number>65536</span><span class=special>);</span>
234
235<span class=comment>// construct a unique_int_list into the segment</span>
236<span class=identifier>unique_int_list</span><span class=special>*</span> <span class=identifier>puil</span><span class=special>=</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>construct</span><span class=special>&lt;</span><span class=identifier>unique_int_list</span><span class=special>&gt;</span>
237 <span class=special>(</span><span class=string>&quot;UniqueIntListID&quot;</span><span class=special>)</span> <span class=comment>// object identifier within the segment
238 // Construction args: first a ctor arg list, then a
239 // shared memory allocator obtained from the segment object.</span>
240 <span class=special>(</span><span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
241 <span class=identifier>unique_int_list</span><span class=special>::</span><span class=identifier>allocator_type</span><span class=special>(</span><span class=identifier>seg</span><span class=special>.</span><span class=identifier>get_segment_manager</span><span class=special>()));</span>
242 </pre></blockquote>
243
244<p>
245The examples section includes a <a href="../examples.html#example12">program</a>
246that further explores this capability.
247</p>
248
249<h2><a name="serialization">Serialization</a></h2>
250
251<p>
252<code>multi_index_container</code>s can be archived and retrieved by means of the
253<a href="../../../serialization/index.html">Boost Serialization Library</a>. Both regular
254and XML archives are supported. The usage is straightforward and does not
255differ from that of any other serializable type. For instance:
256</p>
257
258<blockquote><pre>
259<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_oarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
260<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>archive</span><span class=special>/</span><span class=identifier>text_iarchive</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span>
261<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>fstream</span><span class=special>&gt;</span>
262
263<span class=special>...</span>
264
265<span class=keyword>void</span> <span class=identifier>save</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>)</span>
266<span class=special>{</span>
267 <span class=identifier>std</span><span class=special>::</span><span class=identifier>ofstream</span> <span class=identifier>ofs</span><span class=special>(</span><span class=string>&quot;data&quot;</span><span class=special>);</span>
268 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_oarchive</span> <span class=identifier>oa</span><span class=special>(</span><span class=identifier>ofs</span><span class=special>);</span>
269 <span class=identifier>oa</span><span class=special>&lt;&lt;</span><span class=identifier>es</span><span class=special>;</span>
270<span class=special>}</span>
271
272<span class=keyword>void</span> <span class=identifier>load</span><span class=special>(</span><span class=identifier>employee_set</span><span class=special>&amp;</span> <span class=identifier>es</span><span class=special>)</span>
273<span class=special>{</span>
274 <span class=identifier>std</span><span class=special>::</span><span class=identifier>ifstream</span> <span class=identifier>ifs</span><span class=special>(</span><span class=string>&quot;data&quot;</span><span class=special>);</span>
275 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>archive</span><span class=special>::</span><span class=identifier>text_iarchive</span> <span class=identifier>ia</span><span class=special>(</span><span class=identifier>ifs</span><span class=special>);</span>
276 <span class=identifier>ia</span><span class=special>&gt;&gt;</span><span class=identifier>es</span><span class=special>;</span>
277<span class=special>}</span>
278
279<span class=special>...</span>
280
281<span class=identifier>employee_set</span> <span class=identifier>es</span><span class=special>;</span>
282<span class=special>...</span> <span class=comment>// fill it with data</span>
283<span class=identifier>save</span><span class=special>(</span><span class=identifier>es</span><span class=special>);</span>
284
285<span class=special>...</span>
286
287<span class=identifier>employee_set</span> <span class=identifier>restored_es</span><span class=special>;</span>
288<span class=identifier>load</span><span class=special>(</span><span class=identifier>restored_es</span><span class=special>);</span>
289</pre></blockquote>
290
291<p>
292Serialization capabilities are automatically provided by just linking with
293the appropriate Boost.Serialization library module: it is not necessary
294to explicitly include any header from Boost.Serialization,
295apart from those declaring the type of archive used in the process. If not used,
296however, serialization support can be disabled by globally defining the macro
297<code>BOOST_MULTI_INDEX_DISABLE_SERIALIZATION</code>. Disabling serialization
298for Boost.MultiIndex can yield a small improvement in build times, and may
299be necessary in those defective compilers that fail to correctly process
300Boost.Serialization headers.
301</p>
302
303<p>
304In accordance with Boost.MultiIndex
305<a href="#value_semantics">value semantics</a>, retrieving an
306archived <code>multi_index_container</code> restores not only
307the elements, but also the order they were arranged into for
308every index of the container. There is an exception to this rule,
309though: for <a href="indices.html#hashed_indices">hashed
310indices</a>, no guarantee is made about the order in which elements will
311be iterated in the restored container; in general, it is unwise to rely on
312the ordering of elements of a hashed index, since it can change in arbitrary
313ways during insertion or rehashing --this is precisely the reason why
314hashed indices and TR1 unordered associative containers do not define
315an equality operator.
316</p>
317
318<p>
319Iterators to indices of a <code>multi_index_container</code> can also be
320serialized. Serialization of iterators must be done only after serializing
321their corresponding container.
322</p>
323
324<p>
325<a href="../examples.html#example9">Example 9</a> in the examples section shows
326the serialization capabilities of Boost.MultiIndex.
327</p>
328
329<hr>
330
331<div class="prev_link"><a href="key_extraction.html"><img src="../prev.gif" alt="key extraction" border="0"><br>
332Key extraction
333</a></div>
334<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br>
335Boost.MultiIndex tutorial
336</a></div>
337<div class="next_link"><a href="debug.html"><img src="../next.gif" alt="debugging support" border="0"><br>
338Debugging support
339</a></div><br clear="all" style="clear: all;">
340
341<br>
342
343<p>Revised July 17th 2007</p>
344
345<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
346Distributed under the Boost Software
347License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
348LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
349http://www.boost.org/LICENSE_1_0.txt</a>)
350</p>
351
352</body>
353</html>