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 - Techniques</title> 7<link rel="stylesheet" href="../style.css" type="text/css"> 8<link rel="start" href="../index.html"> 9<link rel="prev" href="debug.html"> 10<link rel="up" href="index.html"> 11<link rel="next" href="../reference/index.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: Techniques</h1> 17 18<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br> 19Debugging support 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="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br> 25Boost.MultiIndex reference 26</a></div><br clear="all" style="clear: all;"> 27 28<hr> 29 30<h2>Contents</h2> 31 32<ul> 33 <li><a href="#emulate_std_containers">Emulating standard containers with 34 <code>multi_index_container</code></a> 35 <ul> 36 <li><a href="#emulate_assoc_containers">Emulation of associative 37 containers</a></li> 38 <li><a href="#emulate_std_list">Emulation of <code>std::list</code></a></li> 39 </ul> 40 </li> 41 <li><a href="#metaprogrammming">Metaprogramming and <code>multi_index_container</code></a> 42 <ul> 43 <li><a href="#mpl_analysis">MPL analysis</a></li> 44 <li><a href="#mpl_synthesis">MPL synthesis</a></li> 45 </ul> 46 </li> 47</ul> 48 49<h2><a name="emulate_std_containers">Emulating standard containers with 50 <code>multi_index_container</code></a></h2> 51 52<h3><a name="emulate_assoc_containers">Emulation of associative 53containers</a></h3> 54 55<p> 56Academic movitations aside, there is a practical interest in emulating standard 57associative containers by means of <code>multi_index_container</code>, namely to take 58advantage of extended functionalities provided by <code>multi_index_container</code> for 59lookup, range querying and updating. 60</p> 61 62<p> 63In order to emulate a <code>std::set</code> one can follow the substitution 64rule: 65</p> 66 67<blockquote><pre> 68<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span> 69 <span class=identifier>multi_index_container</span><span class=special><</span> 70 <span class=identifier>Key</span><span class=special>,</span> 71 <span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> <span class=special>>,</span> 72 <span class=identifier>Allocator</span> 73 <span class=special>></span> 74</pre></blockquote> 75 76<p> 77In the default case where <code>Compare=std::less<Key></code> and 78<code>Allocator=std::allocator<Key></code>, the substitution rule is 79simplified as 80</p> 81 82<blockquote><pre> 83<span class=identifier>std</span><span class=special>::</span><span class=identifier>set</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>-></span> <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> 84</pre></blockquote> 85 86<p> 87The substitution of <code>multi_index_container</code> for <code>std::set</code> keeps 88the whole set of functionality provided by <code>std::set</code>, so in 89principle it is a drop-in replacement needing no further adjustments. 90</p> 91 92<p> 93<code>std::multiset</code> can be emulated in a similar manner, according to the 94following rule: 95</p> 96 97<blockquote><pre> 98<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span> 99 <span class=identifier>multi_index_container</span><span class=special><</span> 100 <span class=identifier>Key</span><span class=special>,</span> 101 <span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> <span class=special>>,</span> 102 <span class=identifier>Allocator</span> 103 <span class=special>></span> 104</pre></blockquote> 105 106<p> 107When default values are taken into consideration, the rule takes the form 108</p> 109 110<blockquote><pre> 111<span class=identifier>std</span><span class=special>::</span><span class=identifier>multiset</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>-></span> 112 <span class=identifier>multi_index_container</span><span class=special><</span> 113 <span class=identifier>Key</span><span class=special>,</span> 114 <span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>identity</span><span class=special><</span><span class=identifier>Key</span><span class=special>></span> <span class=special>></span> <span class=special>></span> 115 <span class=special>></span> 116</pre></blockquote> 117 118<p> 119The emulation of <code>std::multiset</code>s with <code>multi_index_container</code> 120results in a slight difference with respect to the interface offered: the member 121function <code>insert(const value_type&)</code> does not return an 122<code>iterator</code> as in <code>std::multiset</code>s, but rather a 123<code>std::pair<iterator,bool></code> in the spirit of <code>std::set</code>s. 124In this particular case, however, the <code>bool</code> member of the returned 125pair is always <code>true</code>. 126</p> 127 128<p> 129The case of <code>std::map</code>s and <code>std::multimap</code>s does not lend 130itself to such a direct emulation by means of <code>multi_index_container</code>. The main 131problem lies in the fact that elements of a <code>multi_index_container</code> are treated 132as constant, while the <code>std::map</code> and <code>std::multimap</code> handle 133objects of type <code>std::pair<const Key,T></code>, thus allowing for free 134modification of the value part. To overcome this difficulty we need to create an ad 135hoc pair class: 136</p> 137 138<blockquote><pre> 139<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>T1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>T2</span><span class=special>></span> 140<span class=keyword>struct</span> <span class=identifier>mutable_pair</span> 141<span class=special>{</span> 142 <span class=keyword>typedef</span> <span class=identifier>T1</span> <span class=identifier>first_type</span><span class=special>;</span> 143 <span class=keyword>typedef</span> <span class=identifier>T2</span> <span class=identifier>second_type</span><span class=special>;</span> 144 145 <span class=identifier>mutable_pair</span><span class=special>():</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>T1</span><span class=special>()),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>T2</span><span class=special>()){}</span> 146 <span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T1</span><span class=special>&</span> <span class=identifier>f</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>T2</span><span class=special>&</span> <span class=identifier>s</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>f</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>s</span><span class=special>){}</span> 147 <span class=identifier>mutable_pair</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>T1</span><span class=special>,</span><span class=identifier>T2</span><span class=special>>&</span> <span class=identifier>p</span><span class=special>):</span><span class=identifier>first</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>first</span><span class=special>),</span><span class=identifier>second</span><span class=special>(</span><span class=identifier>p</span><span class=special>.</span><span class=identifier>second</span><span class=special>){}</span> 148 149 <span class=identifier>T1</span> <span class=identifier>first</span><span class=special>;</span> 150 <span class=keyword>mutable</span> <span class=identifier>T2</span> <span class=identifier>second</span><span class=special>;</span> 151<span class=special>};</span> 152</pre></blockquote> 153 154<p> 155and so the substitution rules are: 156</p> 157 158<blockquote><pre> 159<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span> 160 <span class=identifier>multi_index_container</span><span class=special><</span> 161 <span class=identifier>Element</span><span class=special>,</span> 162 <span class=identifier>indexed_by</span><span class=special><</span> 163 <span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> 164 <span class=special>>,</span> 165 <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span> 166 <span class=special>></span> 167 168<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Compare</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span> 169 <span class=identifier>multi_index_container</span><span class=special><</span> 170 <span class=identifier>Element</span><span class=special>,</span> 171 <span class=identifier>indexed_by</span><span class=special><</span> 172 <span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>>,</span><span class=identifier>Compare</span><span class=special>></span> 173 <span class=special>>,</span> 174 <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span> 175 <span class=special>></span> 176 177(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span>) 178</pre></blockquote> 179 180<p> 181If default values are considered, the rules take the form: 182</p> 183 184<blockquote><pre> 185<span class=identifier>std</span><span class=special>::</span><span class=identifier>map</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span> 186 <span class=identifier>multi_index_container</span><span class=special><</span> 187 <span class=identifier>Element</span><span class=special>, 188 </span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>></span> <span class=special>></span> <span class=special>></span> 189 <span class=special>></span> 190 191<span class=identifier>std</span><span class=special>::</span><span class=identifier>multimap</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span> 192 <span class=identifier>multi_index_container</span><span class=special><</span> 193 <span class=identifier>Element</span><span class=special>, 194 </span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>ordered_non_unique</span><span class=special><</span><span class=identifier>member</span><span class=special><</span><span class=identifier>Element</span><span class=special>,</span><span class=identifier>Key</span><span class=special>,&</span><span class=identifier>Element</span><span class=special>::</span><span class=identifier>first</span><span class=special>></span> <span class=special>></span> <span class=special>></span> 195 <span class=special>></span> 196 197(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_pair</span><span class=special><</span><span class=identifier>Key</span><span class=special>,</span><span class=identifier>T</span><span class=special>></span>) 198</pre></blockquote> 199 200<p> 201Unlike as with standard sets, the interface of these <code>multi_index_container</code>-emulated 202maps does not exactly conform to that of <code>std::map</code>s and 203<code>std::multimap</code>s. The most obvious difference is the lack of 204<code>operator []</code>, either in read or write mode; this, however, can be 205emulated with appropriate use of <code>find</code> and <code>insert</code>. 206</p> 207 208<p> 209These emulations of standard associative containers with <code>multi_index_container</code> 210are comparable to the original constructs in terms of space and time efficiency. 211See the <a href="../performance.html">performance section</a> for further details. 212</p> 213 214<h3><a name="emulate_std_list">Emulation of <code>std::list</code></a></h3> 215 216<p> 217Unlike the case of associative containers, emulating <code>std::list</code> 218in Boost.MultiIndex does not add any significant functionality, so the following 219is presented merely for completeness sake. 220</p> 221 222<p> 223Much as with standard maps, the main difficulty to overcome when emulating 224<code>std::list</code> derives from the constant nature of elements of a 225<code>multi_index_container</code>. Again, some sort of adaption class is needed, like 226for instance the following: 227</p> 228 229<blockquote><pre> 230<span class=keyword>template</span> <span class=special><</span><span class=keyword>typename</span> <span class=identifier>T</span><span class=special>></span> 231<span class=keyword>struct</span> <span class=identifier>mutable_value</span> 232<span class=special>{</span> 233 <span class=identifier>mutable_value</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>T</span><span class=special>&</span> <span class=identifier>t</span><span class=special>):</span><span class=identifier>t</span><span class=special>(</span><span class=identifier>t</span><span class=special>){}</span> 234 <span class=keyword>operator</span> <span class=identifier>T</span><span class=special>&()</span><span class=keyword>const</span><span class=special>{</span><span class=keyword>return</span> <span class=identifier>t</span><span class=special>;}</span> 235 236<span class=keyword>private</span><span class=special>:</span> 237 <span class=keyword>mutable</span> <span class=identifier>T</span> <span class=identifier>t</span><span class=special>;</span> 238<span class=special>};</span> 239</pre></blockquote> 240 241<p> 242which allows us to use the substitution rule: 243</p> 244 245<blockquote><pre> 246<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special><</span><span class=identifier>T</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>></span> <span class=special>-></span> 247 <span class=identifier>multi_index_container</span><span class=special><</span> 248 <span class=identifier>Element</span><span class=special>,</span> 249 <span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>>,</span> 250 <span class=keyword>typename</span> <span class=identifier>Allocator</span><span class=special>::</span><span class=keyword>template</span> <span class=identifier>rebind</span><span class=special><</span><span class=identifier>Element</span><span class=special>>::</span><span class=identifier>other</span> 251 <span class=special>></span> 252 253(<span class=identifier>with</span> <span class=identifier>Element</span><span class=special>=</span><span class=identifier>mutable_value</span><span class=special><</span><span class=identifier>T</span><span class=special>></span>) 254</pre></blockquote> 255 256<p> 257or, if the default value <code>Allocator=std::allocator<T></code> is used: 258</p> 259 260<blockquote><pre> 261<span class=identifier>std</span><span class=special>::</span><span class=identifier>list</span><span class=special><</span><span class=identifier>T</span><span class=special>></span> <span class=special>-></span> 262 <span class=identifier>multi_index_container</span><span class=special><</span><span class=identifier>mutable_value</span><span class=special><</span><span class=identifier>T</span><span class=special>>,</span><span class=identifier>indexed_by</span><span class=special><</span><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span> <span class=special>></span> 263</pre></blockquote> 264 265<h2><a name="metaprogrammming">Metaprogramming and <code>multi_index_container</code></a></h2> 266 267<p> 268Boost.MultiIndex provides a number of facilities intended to allow the analysis and 269synthesis of <code>multi_index_container</code> instantiations by 270<a href="../../../../libs/mpl/doc/index.html">MPL</a> metaprograms. 271</p> 272 273<h3><a name="mpl_analysis">MPL analysis</a></h3> 274 275<p> 276Given a <code>multi_index_container</code> instantiation, the following nested types are 277provided for compile-time inspection of the various types occurring in the 278definition of the <code>multi_index_container</code>: 279<ul> 280 <li><code>index_specifier_type_list</code>,</li> 281 <li><code>index_type_list</code>,</li> 282 <li><code>iterator_type_list</code>,</li> 283 <li><code>const_iterator_type_list</code>.</li> 284</ul> 285Each of these types is an MPL sequence with as many elements as indices 286comprise the <code>multi_index_container</code>: for instance, the <code>n</code>-th 287element of <code>iterator_type_list</code> is the same as 288<code>nth_index<n>::type::iterator</code>. 289</p> 290 291<p> 292A subtle but important distinction exists between 293<code>index_specifier_type_list</code> and <code>index_type_list</code>: 294the former typelist holds the index <i>specifiers</i> 295with which the <code>multi_index_container</code> instantiation was defined, 296while the latter gives access to the actual implementation classes 297corresponding to each specifier. An example will help to clarify 298this distinction. Given the instantiation: 299</p> 300 301<blockquote><pre> 302<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> 303 <span class=keyword>int</span><span class=special>,</span> 304 <span class=identifier>indexed_by</span><span class=special><</span> 305 <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> 306 <span class=identifier>sequenced</span><span class=special><></span> 307 <span class=special>></span> 308<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span> 309</pre></blockquote> 310 311<p> 312<code>indexed_t::index_specifier_type_list</code> is a type list with 313elements 314</p> 315 316<blockquote><pre> 317<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> 318<span class=identifier>sequenced</span><span class=special><></span> 319</pre></blockquote> 320 321<p> 322while <code>indexed_t::index_type_list</code> holds the types 323</p> 324 325<blockquote><pre> 326<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special><</span><span class=number>0</span><span class=special>>::</span><span class=identifier>type</span> 327<span class=identifier>multi_index_container</span><span class=special>::</span><span class=identifier>nth_type</span><span class=special><</span><span class=number>1</span><span class=special>>::</span><span class=identifier>type</span> 328</pre></blockquote> 329 330<p> 331so the typelists are radically different. Check the 332<a href="../reference/multi_index_container.html#types">reference</a> 333for the exact MPL sequence concepts modeled by these type lists. 334</p> 335 336<h3><a name="mpl_synthesis">MPL synthesis</a></h3> 337 338<p> 339Although typically indices are specified by means of the 340<code>indexed_by</code> construct, actually any MPL sequence of 341index specifiers can be provided instead: 342</p> 343 344<blockquote><pre> 345<span class=keyword>typedef</span> <span class=identifier>mpl</span><span class=special>::</span><span class=identifier>vector</span><span class=special><</span><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><span class=identifier>sequenced</span><span class=special><></span> <span class=special>></span> <span class=identifier>index_list_t</span><span class=special>;</span> 346 347<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> 348 <span class=keyword>int</span><span class=special>,</span> 349 <span class=identifier>index_list_t</span> 350<span class=special>></span> <span class=identifier>indexed_t</span><span class=special>;</span> 351</pre></blockquote> 352 353<p> 354This possibility enables the synthesis of instantiations of 355<code>multi_index_container</code> through MPL metaprograms, as the following 356example shows: 357</p> 358 359<blockquote><pre> 360<span class=comment>// original multi_index_container instantiation</span> 361<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> 362 <span class=keyword>int</span><span class=special>,</span> 363 <span class=identifier>indexed_by</span><span class=special><</span> 364 <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> 365 <span class=special>></span> 366<span class=special>></span> <span class=identifier>indexed_t1</span><span class=special>;</span> 367 368<span class=comment>// we take its index list and add an index</span> 369<span class=keyword>typedef</span> <span class=identifier>boost</span><span class=special>::</span><span class=identifier>mpl</span><span class=special>::</span><span class=identifier>push_front</span><span class=special><</span> 370 <span class=identifier>indexed_t1</span><span class=special>::</span><span class=identifier>index_specifier_type_list</span><span class=special>,</span> 371 <span class=identifier>sequenced</span><span class=special><></span> 372<span class=special>>::</span><span class=identifier>type</span> <span class=identifier>index_list_t</span><span class=special>;</span> 373 374<span class=comment>// augmented multi_index_container</span> 375<span class=keyword>typedef</span> <span class=identifier>multi_index_container</span><span class=special><</span> 376 <span class=keyword>int</span><span class=special>,</span> 377 <span class=identifier>index_list_t</span> 378<span class=special>></span> <span class=identifier>indexed_t2</span><span class=special>;</span> 379</pre></blockquote> 380 381<hr> 382 383<div class="prev_link"><a href="debug.html"><img src="../prev.gif" alt="debugging support" border="0"><br> 384Debugging support 385</a></div> 386<div class="up_link"><a href="index.html"><img src="../up.gif" alt="Boost.MultiIndex tutorial" border="0"><br> 387Boost.MultiIndex tutorial 388</a></div> 389<div class="next_link"><a href="../reference/index.html"><img src="../next.gif" alt="Boost.MultiIndex reference" border="0"><br> 390Boost.MultiIndex reference 391</a></div><br clear="all" style="clear: all;"> 392 393<br> 394 395<p>Revised November 7th 2008</p> 396 397<p>© Copyright 2003-2008 Joaquín M López Muñoz. 398Distributed under the Boost Software 399License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt"> 400LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> 401http://www.boost.org/LICENSE_1_0.txt</a>) 402</p> 403 404</body> 405</html> 406