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 - 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><</span><span class=keyword>typename</span> <span class=identifier>IntegralType</span><span class=special>></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>)<(</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><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>,</span><span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>></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><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(</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>&</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>&</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><</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>></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><</span><span class=identifier>i</span><span class=special>>::</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><</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><</span> 134 <span class=identifier>hashed_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span> 135 <span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span> <span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</span> 136 <span class=identifier>sequenced</span><span class=special><>,</span> 137 <span class=identifier>random_access</span><span class=special><></span> 138 <span class=special>></span> 139<span class=special>></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><</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><</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><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span> 152 <span class=identifier>boost</span><span class=special>::</span><span class=identifier>hash</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span> 153 <span class=identifier>std</span><span class=special>::</span><span class=identifier>equal_to</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</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><</span> 157 <span class=identifier>identity</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>,</span> 158 <span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>></span> <span class=special>>,</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><>,</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><></span> 165<span class=special>></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><</span><span class=number>0</span><span class=special>>::</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><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(),</span><span class=identifier>modulo_less</span><span class=special><</span><span class=keyword>unsigned</span> <span class=keyword>int</span><span class=special>>(</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><</span><span class=number>2</span><span class=special>>::</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><</span><span class=number>3</span><span class=special>>::</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><</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>></span> 209<span class=preprocessor>#include</span> <span class=special><</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>></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><</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>></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><</span> 221 <span class=keyword>int</span><span class=special>,</span> 222 <span class=identifier>indexed_by</span><span class=special><</span> 223 <span class=identifier>sequenced</span><span class=special><>,</span> 224 <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span> 225 <span class=special>>,</span> 226 <span class=identifier>shared_int_allocator</span> 227<span class=special>></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>"SharedMemoryID"</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><</span><span class=identifier>unique_int_list</span><span class=special>></span> 237 <span class=special>(</span><span class=string>"UniqueIntListID"</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><</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>></span> 260<span class=preprocessor>#include</span> <span class=special><</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>></span> 261<span class=preprocessor>#include</span> <span class=special><</span><span class=identifier>fstream</span><span class=special>></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>&</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>"data"</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><<</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>&</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>"data"</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>>></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>© Copyright 2003-2007 Joaquín M López Muñ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> 354