• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Advanced lookup and insertion functions for associative containers</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../intrusive.html" title="Chapter 19. Boost.Intrusive">
10<link rel="prev" href="bst_hooks.html" title="Binary search tree hooks: bs_set_base_hook and bs_set_member_hook">
11<link rel="next" href="erasing_and_disposing.html" title="Erasing and disposing values from Boost.Intrusive containers">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="bst_hooks.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../intrusive.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="erasing_and_disposing.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="intrusive.advanced_lookups_insertions"></a><a class="link" href="advanced_lookups_insertions.html" title="Advanced lookup and insertion functions for associative containers">Advanced lookup
29    and insertion functions for associative containers</a>
30</h2></div></div></div>
31<div class="toc"><dl class="toc">
32<dt><span class="section"><a href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_lookups">Advanced
33      lookups</a></span></dt>
34<dt><span class="section"><a href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_insertions">Advanced
35      insertions</a></span></dt>
36<dt><span class="section"><a href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.positional_insertions">Positional
37      insertions</a></span></dt>
38</dl></div>
39<div class="section">
40<div class="titlepage"><div><div><h3 class="title">
41<a name="intrusive.advanced_lookups_insertions.advanced_lookups"></a><a class="link" href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_lookups" title="Advanced lookups">Advanced
42      lookups</a>
43</h3></div></div></div>
44<div class="toc"><dl class="toc"><dt><span class="section"><a href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_lookups.advanced_lookups_example">Example</a></span></dt></dl></div>
45<p>
46        <span class="bold"><strong>Boost.Intrusive</strong></span> associative containers offer
47        an interface similar to STL associative containers. However, STL's ordered
48        and unordered simple associative containers (<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span></code>,
49        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">multiset</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_set</span></code>
50        and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_multiset</span></code>) have some inefficiencies
51        caused by the interface in several search, insertion or erasure functions
52        (<code class="computeroutput"><span class="identifier">equal_range</span></code>, <code class="computeroutput"><span class="identifier">lower_bound</span></code>, <code class="computeroutput"><span class="identifier">upper_bound</span></code>,
53        <code class="computeroutput"><span class="identifier">find</span></code>, <code class="computeroutput"><span class="identifier">insert</span></code>,
54        <code class="computeroutput"><span class="identifier">erase</span></code>...): the user can only
55        operate with <code class="computeroutput"><span class="identifier">value_type</span></code> objects
56        or (starting from C++11), <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3657.htm" target="_top">heterogeneous
57        comparison lookups</a> which are not flexible enough as <code class="computeroutput"><span class="identifier">key_compare</span></code> shall support the comparison
58        between the provided key and <code class="computeroutput"><span class="identifier">value_type</span></code>,
59        which precludes the use of user-defined comparison objects that can partition
60        the search in a compatible but advanced way.
61      </p>
62<p>
63        To solve these problems, <span class="bold"><strong>Boost.Intrusive</strong></span>
64        containers offers functions where a key type different from <code class="computeroutput"><span class="identifier">key_type</span></code> and a comparison object are provided
65        by the user. This applies to: * equal_range * lower_bound * upper_bound *
66        count * find * erase
67      </p>
68<p>
69        Requirements for such functions are:
70      </p>
71<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
72<li class="listitem">
73            For unordered container the provided comparison and hashing function
74            with the given key shall induce the same hash and equivalence as <code class="computeroutput"><span class="identifier">key_compare</span></code> and <code class="computeroutput"><span class="identifier">hasher</span></code>.
75          </li>
76<li class="listitem">
77            For ordered associative containers, lookup and erasure functions, the
78            container to be searched shall be partitioned in regards to the supplied
79            comparison object and key.
80          </li>
81</ul></div>
82<p>
83        For more details, see <span class="bold"><strong>Requires</strong></span> clauses of
84        such functions in the reference.
85      </p>
86<div class="section">
87<div class="titlepage"><div><div><h4 class="title">
88<a name="intrusive.advanced_lookups_insertions.advanced_lookups.advanced_lookups_example"></a><a class="link" href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_lookups.advanced_lookups_example" title="Example">Example</a>
89</h4></div></div></div>
90<p>
91          Imagine that the object to be searched is quite expensive to construct
92          (called <code class="computeroutput"><span class="identifier">Expensive</span></code> in the
93          example):
94        </p>
95<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
96<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">unordered_set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
97<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cstring</span><span class="special">&gt;</span>
98
99<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive</span><span class="special">;</span>
100
101<span class="comment">// Hash function for strings</span>
102<span class="keyword">struct</span> <span class="identifier">StrHasher</span>
103<span class="special">{</span>
104   <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">)</span> <span class="keyword">const</span>
105   <span class="special">{</span>
106      <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">seed</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
107      <span class="keyword">for</span><span class="special">(;</span> <span class="special">*</span><span class="identifier">str</span><span class="special">;</span> <span class="special">++</span><span class="identifier">str</span><span class="special">)</span>   <span class="identifier">boost</span><span class="special">::</span><span class="identifier">hash_combine</span><span class="special">(</span><span class="identifier">seed</span><span class="special">,</span> <span class="special">*</span><span class="identifier">str</span><span class="special">);</span>
108      <span class="keyword">return</span> <span class="identifier">seed</span><span class="special">;</span>
109   <span class="special">}</span>
110<span class="special">};</span>
111
112<span class="keyword">class</span> <span class="identifier">Expensive</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">set_base_hook</span><span class="special">&lt;&gt;,</span> <span class="keyword">public</span> <span class="identifier">unordered_set_base_hook</span><span class="special">&lt;&gt;</span>
113<span class="special">{</span>
114   <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">key_</span><span class="special">;</span>
115   <span class="comment">// Other members...</span>
116
117   <span class="keyword">public</span><span class="special">:</span>
118   <span class="identifier">Expensive</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">key</span><span class="special">)</span>
119      <span class="special">:</span>  <span class="identifier">key_</span><span class="special">(</span><span class="identifier">key</span><span class="special">)</span>
120      <span class="special">{}</span>  <span class="comment">//other expensive initializations...</span>
121
122   <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">get_key</span><span class="special">()</span> <span class="keyword">const</span>
123      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">key_</span><span class="special">;</span>   <span class="special">}</span>
124
125   <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span>  <span class="special">(</span><span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">b</span><span class="special">)</span>
126      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">key_</span> <span class="special">&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">key_</span><span class="special">;</span>  <span class="special">}</span>
127
128   <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">b</span><span class="special">)</span>
129      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">key_</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">key_</span><span class="special">;</span>  <span class="special">}</span>
130
131   <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">object</span><span class="special">)</span>
132      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">StrHasher</span><span class="special">()(</span><span class="identifier">object</span><span class="special">.</span><span class="identifier">get_key</span><span class="special">().</span><span class="identifier">c_str</span><span class="special">());</span>  <span class="special">}</span>
133<span class="special">};</span>
134
135<span class="comment">// A set and unordered_set that store Expensive objects</span>
136<span class="keyword">typedef</span> <span class="identifier">set</span><span class="special">&lt;</span><span class="identifier">Expensive</span><span class="special">&gt;</span>           <span class="identifier">Set</span><span class="special">;</span>
137<span class="keyword">typedef</span> <span class="identifier">unordered_set</span><span class="special">&lt;</span><span class="identifier">Expensive</span><span class="special">&gt;</span> <span class="identifier">UnorderedSet</span><span class="special">;</span>
138
139<span class="comment">// Search functions</span>
140<span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">get_from_set</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Set</span> <span class="special">&amp;</span><span class="identifier">set_object</span><span class="special">)</span>
141<span class="special">{</span>
142   <span class="identifier">Set</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">Expensive</span><span class="special">(</span><span class="identifier">key</span><span class="special">));</span>
143   <span class="keyword">if</span><span class="special">(</span> <span class="identifier">it</span> <span class="special">==</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">)</span>     <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
144   <span class="keyword">return</span> <span class="special">&amp;*</span><span class="identifier">it</span><span class="special">;</span>
145<span class="special">}</span>
146
147<span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">get_from_uset</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">UnorderedSet</span> <span class="special">&amp;</span><span class="identifier">uset_object</span><span class="special">)</span>
148<span class="special">{</span>
149   <span class="identifier">UnorderedSet</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">Expensive</span> <span class="special">(</span><span class="identifier">key</span><span class="special">));</span>
150   <span class="keyword">if</span><span class="special">(</span> <span class="identifier">it</span> <span class="special">==</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">)</span>  <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
151   <span class="keyword">return</span> <span class="special">&amp;*</span><span class="identifier">it</span><span class="special">;</span>
152<span class="special">}</span>
153</pre>
154<p>
155          If "key" c-string is quite long <code class="computeroutput"><span class="identifier">Expensive</span></code>
156          has to construct a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
157          using heap memory. Like <code class="computeroutput"><span class="identifier">Expensive</span></code>,
158          many times the only member taking part in ordering issues is just a small
159          part of the class. E.g.: with <code class="computeroutput"><span class="identifier">Expensive</span></code>,
160          only the internal <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> is needed to compare the object.
161        </p>
162<p>
163          In both containers, if we call <code class="computeroutput"><span class="identifier">get_from_set</span><span class="special">/</span><span class="identifier">get_from_unordered_set</span></code>
164          in a loop, we might get a performance penalty, because we are forced to
165          create a whole <code class="computeroutput"><span class="identifier">Expensive</span></code>
166          object to be able to find an equivalent one.
167        </p>
168<p>
169          Sometimes the problem is not only performance-related, as we <span class="bold"><strong>might not have enough information to construct the object</strong></span>
170          but we might <span class="bold"><strong>have enough information to find the
171          object</strong></span>. In this case, a name is enough to search <code class="computeroutput"><span class="identifier">Expensive</span></code> objects in the container but
172          constructing an <code class="computeroutput"><span class="identifier">Expensive</span></code>
173          object might require more information that the searcher might not have.
174        </p>
175<p>
176          To solve this, we can use the functions that take any type comparable with
177          the value and a the 'compatible' comparison object (and hash, when the
178          associative container is unordered) Let's see optimized search function:
179        </p>
180<pre class="programlisting"><span class="comment">// These compare Expensive and a c-string</span>
181<span class="keyword">struct</span> <span class="identifier">StrExpComp</span>
182<span class="special">{</span>
183   <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span>
184   <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">get_key</span><span class="special">().</span><span class="identifier">c_str</span><span class="special">())</span> <span class="special">&lt;</span> <span class="number">0</span><span class="special">;</span>  <span class="special">}</span>
185
186   <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">c</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">)</span> <span class="keyword">const</span>
187   <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">get_key</span><span class="special">().</span><span class="identifier">c_str</span><span class="special">(),</span> <span class="identifier">str</span><span class="special">)</span> <span class="special">&lt;</span> <span class="number">0</span><span class="special">;</span>  <span class="special">}</span>
188<span class="special">};</span>
189
190<span class="keyword">struct</span> <span class="identifier">StrExpEqual</span>
191<span class="special">{</span>
192   <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span>
193   <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">get_key</span><span class="special">().</span><span class="identifier">c_str</span><span class="special">())</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span>  <span class="special">}</span>
194
195   <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">const</span> <span class="identifier">Expensive</span> <span class="special">&amp;</span><span class="identifier">c</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">)</span> <span class="keyword">const</span>
196   <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">strcmp</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">get_key</span><span class="special">().</span><span class="identifier">c_str</span><span class="special">(),</span> <span class="identifier">str</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span>  <span class="special">}</span>
197<span class="special">};</span>
198
199<span class="comment">// Optimized search functions</span>
200<span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">get_from_set_optimized</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Set</span> <span class="special">&amp;</span><span class="identifier">set_object</span><span class="special">)</span>
201<span class="special">{</span>
202   <span class="identifier">Set</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">StrExpComp</span><span class="special">());</span>
203   <span class="keyword">if</span><span class="special">(</span> <span class="identifier">it</span> <span class="special">==</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">)</span>   <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
204   <span class="keyword">return</span> <span class="special">&amp;*</span><span class="identifier">it</span><span class="special">;</span>
205<span class="special">}</span>
206
207<span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">get_from_uset_optimized</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">UnorderedSet</span> <span class="special">&amp;</span><span class="identifier">uset_object</span><span class="special">)</span>
208<span class="special">{</span>
209   <span class="identifier">UnorderedSet</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">StrHasher</span><span class="special">(),</span> <span class="identifier">StrExpEqual</span><span class="special">());</span>
210   <span class="keyword">if</span><span class="special">(</span> <span class="identifier">it</span> <span class="special">==</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">)</span>  <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
211   <span class="keyword">return</span> <span class="special">&amp;*</span><span class="identifier">it</span><span class="special">;</span>
212<span class="special">}</span>
213</pre>
214</div>
215</div>
216<div class="section">
217<div class="titlepage"><div><div><h3 class="title">
218<a name="intrusive.advanced_lookups_insertions.advanced_insertions"></a><a class="link" href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_insertions" title="Advanced insertions">Advanced
219      insertions</a>
220</h3></div></div></div>
221<div class="toc"><dl class="toc"><dt><span class="section"><a href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_insertions.advanced_insertions_example">Example</a></span></dt></dl></div>
222<p>
223        A similar issue happens with insertions in simple ordered and unordered associative
224        containers with unique keys (<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span></code> and
225        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_set</span></code>). In these containers, if
226        a value is already present, the value to be inserted is discarded. With expensive
227        values, if the value is already present, we can suffer efficiency problems.
228      </p>
229<p>
230        <code class="computeroutput"><a class="link" href="../boost/intrusive/set.html" title="Class template set">set</a></code> and <code class="computeroutput"><a class="link" href="../boost/intrusive/unordered_set.html" title="Class template unordered_set">unordered_set</a></code>-like
231        containers have insertion functions (<code class="computeroutput"><span class="identifier">insert_check</span></code>,
232        <code class="computeroutput"><span class="identifier">insert_unique_check</span></code>,...)
233        to check efficiently, without constructing the value, if a value is present
234        or not and if it's not present, a function to insert it immediately (<code class="computeroutput"><span class="identifier">insert_commit</span></code>) without any further lookup.
235        Requirements for functions that check the existence of such value are:
236      </p>
237<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
238<li class="listitem">
239            For unordered container the provided comparison and hashing function
240            with the given key shall induce the same hash and equivalence as <code class="computeroutput"><span class="identifier">key_compare</span></code> and <code class="computeroutput"><span class="identifier">hasher</span></code>.
241          </li>
242<li class="listitem">
243            For ordered associative containers, the provided comparison function
244            with the given key, shall induce the same strict weak order as <code class="computeroutput"><span class="identifier">key_compare</span></code>.
245          </li>
246</ul></div>
247<p>
248        To sum up, <code class="computeroutput"><span class="identifier">insert_check</span></code> is
249        similar to a normal <code class="computeroutput"><span class="identifier">insert</span></code>
250        but:
251      </p>
252<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
253<li class="listitem">
254            <code class="computeroutput"><span class="identifier">insert_check</span></code> can be used
255            with arbitrary keys
256          </li>
257<li class="listitem">
258            if the insertion is possible (there is no equivalent value) <code class="computeroutput"><span class="identifier">insert_check</span></code> collects all the needed
259            information in an <code class="computeroutput"><span class="identifier">insert_commit_data</span></code>
260            structure, so that <code class="computeroutput"><span class="identifier">insert_commit</span></code>:
261            <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
262<li class="listitem">
263                  <span class="bold"><strong>does not execute</strong></span> further comparisons
264                </li>
265<li class="listitem">
266                  can be executed with <span class="bold"><strong>constant-time complexity</strong></span>
267                </li>
268<li class="listitem">
269                  has <span class="bold"><strong>no-throw guarantee</strong></span>.
270                </li>
271</ul></div>
272          </li>
273</ul></div>
274<p>
275        These functions must be used with care, no other insertion or erasure must
276        be executed between an <code class="computeroutput"><span class="identifier">insert_check</span></code>
277        and an <code class="computeroutput"><span class="identifier">insert_commit</span></code> pair.
278        Otherwise, the behaviour is undefined.
279      </p>
280<p>
281        See <code class="computeroutput"><a class="link" href="../boost/intrusive/set.html" title="Class template set">set</a></code> and <code class="computeroutput"><a class="link" href="../boost/intrusive/unordered_set.html" title="Class template unordered_set">unordered_set</a></code>-like containers'
282        reference for more information about <code class="computeroutput"><span class="identifier">insert_check</span></code>
283        and <code class="computeroutput"><span class="identifier">insert_commit</span></code>.
284      </p>
285<p>
286        With multiple ordered and unordered associative containers (<code class="computeroutput"><a class="link" href="../boost/intrusive/multiset.html" title="Class template multiset">multiset</a></code>
287        and <code class="computeroutput"><a class="link" href="../boost/intrusive/unordered_multiset.html" title="Class template unordered_multiset">unordered_multiset</a></code>)
288        there is no need for these advanced insertion functions, since insertions
289        are always successful.
290      </p>
291<div class="section">
292<div class="titlepage"><div><div><h4 class="title">
293<a name="intrusive.advanced_lookups_insertions.advanced_insertions.advanced_insertions_example"></a><a class="link" href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.advanced_insertions.advanced_insertions_example" title="Example">Example</a>
294</h4></div></div></div>
295<p>
296          For example, using the same <code class="computeroutput"><span class="identifier">Expensive</span></code>
297          class, this function can be inefficient:
298        </p>
299<pre class="programlisting"><span class="comment">// Insertion functions</span>
300<span class="keyword">bool</span> <span class="identifier">insert_to_set</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Set</span> <span class="special">&amp;</span><span class="identifier">set_object</span><span class="special">)</span>
301<span class="special">{</span>
302   <span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">pobject</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Expensive</span><span class="special">(</span><span class="identifier">key</span><span class="special">);</span>
303   <span class="keyword">bool</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(*</span><span class="identifier">pobject</span><span class="special">).</span><span class="identifier">second</span><span class="special">;</span>
304   <span class="keyword">if</span><span class="special">(!</span><span class="identifier">success</span><span class="special">)</span>   <span class="keyword">delete</span> <span class="identifier">pobject</span><span class="special">;</span>
305   <span class="keyword">return</span> <span class="identifier">success</span><span class="special">;</span>
306<span class="special">}</span>
307
308<span class="keyword">bool</span> <span class="identifier">insert_to_uset</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">UnorderedSet</span> <span class="special">&amp;</span><span class="identifier">uset_object</span><span class="special">)</span>
309<span class="special">{</span>
310   <span class="identifier">Expensive</span> <span class="special">*</span><span class="identifier">pobject</span> <span class="special">=</span> <span class="keyword">new</span> <span class="identifier">Expensive</span><span class="special">(</span><span class="identifier">key</span><span class="special">);</span>
311   <span class="keyword">bool</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(*</span><span class="identifier">pobject</span><span class="special">).</span><span class="identifier">second</span><span class="special">;</span>
312   <span class="keyword">if</span><span class="special">(!</span><span class="identifier">success</span><span class="special">)</span>   <span class="keyword">delete</span> <span class="identifier">pobject</span><span class="special">;</span>
313   <span class="keyword">return</span> <span class="identifier">success</span><span class="special">;</span>
314<span class="special">}</span>
315</pre>
316<p>
317          If the object is already present, we are constructing an <code class="computeroutput"><span class="identifier">Expensive</span></code> that will be discarded, and
318          this is a waste of resources. Instead of that, let's use <code class="computeroutput"><span class="identifier">insert_check</span></code> and <code class="computeroutput"><span class="identifier">insert_commit</span></code>
319          functions:
320        </p>
321<pre class="programlisting"><span class="comment">// Optimized insertion functions</span>
322<span class="keyword">bool</span> <span class="identifier">insert_to_set_optimized</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">Set</span> <span class="special">&amp;</span><span class="identifier">set_object</span><span class="special">)</span>
323<span class="special">{</span>
324   <span class="identifier">Set</span><span class="special">::</span><span class="identifier">insert_commit_data</span> <span class="identifier">insert_data</span><span class="special">;</span>
325   <span class="keyword">bool</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">insert_check</span><span class="special">(</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">StrExpComp</span><span class="special">(),</span> <span class="identifier">insert_data</span><span class="special">).</span><span class="identifier">second</span><span class="special">;</span>
326   <span class="keyword">if</span><span class="special">(</span><span class="identifier">success</span><span class="special">)</span> <span class="identifier">set_object</span><span class="special">.</span><span class="identifier">insert_commit</span><span class="special">(*</span><span class="keyword">new</span> <span class="identifier">Expensive</span><span class="special">(</span><span class="identifier">key</span><span class="special">),</span> <span class="identifier">insert_data</span><span class="special">);</span>
327   <span class="keyword">return</span> <span class="identifier">success</span><span class="special">;</span>
328<span class="special">}</span>
329
330<span class="keyword">bool</span> <span class="identifier">insert_to_uset_optimized</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">key</span><span class="special">,</span> <span class="identifier">UnorderedSet</span> <span class="special">&amp;</span><span class="identifier">uset_object</span><span class="special">)</span>
331<span class="special">{</span>
332   <span class="identifier">UnorderedSet</span><span class="special">::</span><span class="identifier">insert_commit_data</span> <span class="identifier">insert_data</span><span class="special">;</span>
333   <span class="keyword">bool</span> <span class="identifier">success</span> <span class="special">=</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">insert_check</span>
334      <span class="special">(</span><span class="identifier">key</span><span class="special">,</span> <span class="identifier">StrHasher</span><span class="special">(),</span> <span class="identifier">StrExpEqual</span><span class="special">(),</span> <span class="identifier">insert_data</span><span class="special">).</span><span class="identifier">second</span><span class="special">;</span>
335   <span class="keyword">if</span><span class="special">(</span><span class="identifier">success</span><span class="special">)</span> <span class="identifier">uset_object</span><span class="special">.</span><span class="identifier">insert_commit</span><span class="special">(*</span><span class="keyword">new</span> <span class="identifier">Expensive</span><span class="special">(</span><span class="identifier">key</span><span class="special">),</span> <span class="identifier">insert_data</span><span class="special">);</span>
336   <span class="keyword">return</span> <span class="identifier">success</span><span class="special">;</span>
337<span class="special">}</span>
338</pre>
339</div>
340</div>
341<div class="section">
342<div class="titlepage"><div><div><h3 class="title">
343<a name="intrusive.advanced_lookups_insertions.positional_insertions"></a><a class="link" href="advanced_lookups_insertions.html#intrusive.advanced_lookups_insertions.positional_insertions" title="Positional insertions">Positional
344      insertions</a>
345</h3></div></div></div>
346<p>
347        Some ordered associative containers offer low-level functions to bypass ordering
348        checks and insert nodes directly in desired tree positions. These functions
349        are provided for performance reasons when values to be inserted in the container
350        are known to fulfill order (sets and multisets) and uniqueness (sets) invariants.
351        A typical usage of these functions is when intrusive associative containers
352        are used to build non-intrusive containers and the programmer wants to speed
353        up assignments from other associative containers: if the ordering and uniqueness
354        properties are the same, there is no need to waste time checking the position
355        of each source value, because values are already ordered: back insertions
356        will be much more efficient.
357      </p>
358<p>
359        <span class="bold"><strong>Note:</strong></span> These functions <span class="bold"><strong>don't
360        check preconditions</strong></span> so they must used with care. They are low-level
361        operations that <span class="bold"><strong>will break container invariants if
362        ordering and uniqueness preconditions are not assured by the caller.</strong></span>
363      </p>
364<p>
365        Let's see an example:
366      </p>
367<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">intrusive</span><span class="special">/</span><span class="identifier">set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
368<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
369<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
370<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
371
372<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">intrusive</span><span class="special">;</span>
373
374<span class="comment">//A simple class with a set hook</span>
375<span class="keyword">class</span> <span class="identifier">MyClass</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">set_base_hook</span><span class="special">&lt;&gt;</span>
376<span class="special">{</span>
377   <span class="keyword">public</span><span class="special">:</span>
378   <span class="keyword">int</span> <span class="identifier">int_</span><span class="special">;</span>
379
380   <span class="identifier">MyClass</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">:</span>  <span class="identifier">int_</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{}</span>
381   <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&lt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">b</span><span class="special">)</span>
382      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">int_</span> <span class="special">&lt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">int_</span><span class="special">;</span>  <span class="special">}</span>
383   <span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">&gt;</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">a</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">b</span><span class="special">)</span>
384      <span class="special">{</span>  <span class="keyword">return</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">int_</span> <span class="special">&gt;</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">int_</span><span class="special">;</span>  <span class="special">}</span>
385<span class="special">};</span>
386
387<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
388<span class="special">{</span>
389   <span class="comment">//Create some ORDERED elements</span>
390   <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="identifier">values</span><span class="special">;</span>
391   <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>  <span class="identifier">values</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">MyClass</span><span class="special">(</span><span class="identifier">i</span><span class="special">));</span>
392
393   <span class="special">{</span>  <span class="comment">//Data is naturally ordered in the vector with the same criteria</span>
394      <span class="comment">//as multiset's comparison predicate, so we can just push back</span>
395      <span class="comment">//all elements, which is more efficient than normal insertion</span>
396      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="identifier">mset</span><span class="special">;</span>
397      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>  <span class="identifier">mset</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">values</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span>
398
399      <span class="comment">//Now check orderd invariant</span>
400      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;::</span><span class="identifier">const_iterator</span> <span class="identifier">next</span><span class="special">(</span><span class="identifier">mset</span><span class="special">.</span><span class="identifier">cbegin</span><span class="special">()),</span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">next</span><span class="special">++);</span>
401      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">99</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">,</span> <span class="special">++</span><span class="identifier">it</span><span class="special">,</span> <span class="special">++</span><span class="identifier">next</span><span class="special">)</span> <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">it</span> <span class="special">&lt;</span> <span class="special">*</span><span class="identifier">next</span><span class="special">);</span>
402   <span class="special">}</span>
403   <span class="special">{</span>  <span class="comment">//Now the correct order for the set is the reverse order</span>
404      <span class="comment">//so let's push front all elements</span>
405      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">compare</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">greater</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">mset</span><span class="special">;</span>
406      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">100</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>  <span class="identifier">mset</span><span class="special">.</span><span class="identifier">push_front</span><span class="special">(</span><span class="identifier">values</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span>
407
408      <span class="comment">//Now check orderd invariant</span>
409      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">,</span> <span class="identifier">compare</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">greater</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;::</span>
410         <span class="identifier">const_iterator</span> <span class="identifier">next</span><span class="special">(</span><span class="identifier">mset</span><span class="special">.</span><span class="identifier">cbegin</span><span class="special">()),</span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">next</span><span class="special">++);</span>
411      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">99</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">,</span> <span class="special">++</span><span class="identifier">it</span><span class="special">,</span> <span class="special">++</span><span class="identifier">next</span><span class="special">)</span> <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">it</span> <span class="special">&gt;</span> <span class="special">*</span><span class="identifier">next</span><span class="special">);</span>
412   <span class="special">}</span>
413   <span class="special">{</span>  <span class="comment">//Now push the first and the last and insert the rest</span>
414      <span class="comment">//before the last position using "insert_before"</span>
415      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="identifier">mset</span><span class="special">;</span>
416      <span class="identifier">mset</span><span class="special">.</span><span class="identifier">insert_before</span><span class="special">(</span><span class="identifier">mset</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">[</span><span class="number">0</span><span class="special">]);</span>
417      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;::</span><span class="identifier">const_iterator</span> <span class="identifier">pos</span> <span class="special">=</span>
418         <span class="identifier">mset</span><span class="special">.</span><span class="identifier">insert_before</span><span class="special">(</span><span class="identifier">mset</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">[</span><span class="number">99</span><span class="special">]);</span>
419      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">99</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span>  <span class="identifier">mset</span><span class="special">.</span><span class="identifier">insert_before</span><span class="special">(</span><span class="identifier">pos</span><span class="special">,</span> <span class="identifier">values</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span>
420
421      <span class="comment">//Now check orderd invariant</span>
422      <span class="identifier">multiset</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;::</span><span class="identifier">const_iterator</span> <span class="identifier">next</span><span class="special">(</span><span class="identifier">mset</span><span class="special">.</span><span class="identifier">cbegin</span><span class="special">()),</span> <span class="identifier">it</span><span class="special">(</span><span class="identifier">next</span><span class="special">++);</span>
423      <span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">99</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">,</span> <span class="special">++</span><span class="identifier">it</span><span class="special">,</span> <span class="special">++</span><span class="identifier">next</span><span class="special">)</span> <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">it</span> <span class="special">&lt;</span> <span class="special">*</span><span class="identifier">next</span><span class="special">);</span>
424   <span class="special">}</span>
425
426   <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
427<span class="special">}</span>
428</pre>
429</div>
430<p>
431      For more information about advanced lookup and insertion functions see associative
432      containers' documentation (e.g. <code class="computeroutput"><a class="link" href="../boost/intrusive/set.html" title="Class template set">set</a></code>,
433      <code class="computeroutput"><a class="link" href="../boost/intrusive/multiset.html" title="Class template multiset">multiset</a></code>, <code class="computeroutput"><a class="link" href="../boost/intrusive/unordered_set.html" title="Class template unordered_set">unordered_set</a></code> and <code class="computeroutput"><a class="link" href="../boost/intrusive/unordered_multiset.html" title="Class template unordered_multiset">unordered_multiset</a></code> references).
434    </p>
435</div>
436<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
437<td align="left"></td>
438<td align="right"><div class="copyright-footer">Copyright © 2005 Olaf Krzikalla<br>Copyright © 2006-2015 Ion Gaztanaga<p>
439        Distributed under the Boost Software License, Version 1.0. (See accompanying
440        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
441      </p>
442</div></td>
443</tr></table>
444<hr>
445<div class="spirit-nav">
446<a accesskey="p" href="bst_hooks.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../intrusive.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="erasing_and_disposing.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
447</div>
448</body>
449</html>
450