mirror of
https://github.com/boostorg/multi_index.git
synced 2026-01-19 04:22:11 +00:00
updated docs
This commit is contained in:
@@ -308,6 +308,16 @@ requirements.
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -474,7 +484,9 @@ local_iterator<br>
|
||||
const_local_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types are forward iterators.
|
||||
These types are forward iterators. They depend only on <code>node_type</code> and whether
|
||||
the index is unique or not (this implies that, for instance, iterators to elements transferred
|
||||
from a unique index to a non-unique one will become invalid).
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
@@ -925,6 +937,89 @@ with <code>mod'</code> and <code>back</code> defined in such a way that
|
||||
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
|
||||
</blockquote>
|
||||
|
||||
<code>template<typename Index> void merge(Index&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>merge</span><span class=special>(</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
template<typename Index> std::pair<iterator,bool> merge(<br>
|
||||
Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, transfers the node of the element referred to by <code>i</code> into the
|
||||
<code>multi_index_container</code> to which the destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
|
||||
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to <code>*i</code>
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if transfer took place or the source and destination
|
||||
containers are the same. If <code>p.second</code> is <code>true</code>,
|
||||
<code>p.first</code> points to <code>*i</code>; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise strong.
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
template<typename Index> void merge(<br>
|
||||
Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, for each node in [<code>first</code>,<code>last</code>), in this order,
|
||||
the node is transferred to the <code>multi_index_container</code> to which the
|
||||
destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> For any index in the source container having the same
|
||||
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to the transferred elements
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(m*(I(n+m)+D(x.size())))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise basic.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="observers">Observers</a></h4>
|
||||
|
||||
<p>Apart from standard <code>hash_function</code> and <code>key_eq</code>,
|
||||
@@ -1275,7 +1370,7 @@ Sequenced indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 29th 2021</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -42,6 +42,7 @@ Ranked indices
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#iterators">Iterators</a></li>
|
||||
<li><a href="#modifiers">Modifiers</a></li>
|
||||
@@ -310,6 +311,16 @@ do not exactly conform to or are not mandated by the standard requirements.
|
||||
<span class=keyword>void</span> <span class=identifier>swap</span><span class=special>(</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>clear</span><span class=special>()</span><span class=keyword>noexcept</span><span class=special>;</span>
|
||||
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>merge</span><span class=special>(</span>
|
||||
<span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=comment>// observers:</span>
|
||||
|
||||
<span class=identifier>key_from_value</span> <span class=identifier>key_extractor</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
|
||||
@@ -465,6 +476,15 @@ must be a model of <a href="key_extraction.html#key_extractors">
|
||||
on elements of <code>KeyFromValue::result_type</code>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -911,6 +931,89 @@ with <code>mod'</code> and <code>back</code> defined in such a way that
|
||||
<code>key</code> is the internal <code>KeyFromValue</code> object of the index.
|
||||
</blockquote>
|
||||
|
||||
<a name="merge"><code>template<typename Index> void merge(Index&& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>merge</span><span class=special>(</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
template<typename Index> std::pair<iterator,bool> merge(<br>
|
||||
Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, transfers the node of the element referred to by <code>i</code> into the
|
||||
<code>multi_index_container</code> to which the destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
|
||||
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to <code>*i</code>
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if transfer took place or the source and destination
|
||||
containers are the same. If <code>p.second</code> is <code>true</code>,
|
||||
<code>p.first</code> points to <code>*i</code>; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise strong.
|
||||
</blockquote>
|
||||
|
||||
<code>
|
||||
template<typename Index> void merge(<br>
|
||||
Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>. <code>get_allocator()==x.get_allocator()</code>.
|
||||
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
|
||||
<b>Effects:</b> Does nothing if the source and destination containers are the same;
|
||||
otherwise, for each node in [<code>first</code>,<code>last</code>), in this order,
|
||||
the node is transferred to the <code>multi_index_container</code> to which the
|
||||
destination index belongs if
|
||||
<ul>
|
||||
<li>the index is non-unique OR no other element exists with
|
||||
equivalent key,</li>
|
||||
<li>AND insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
</ul>
|
||||
Note that no element is copied or destroyed in the process.<br>
|
||||
<b>Postconditions:</b> For any index in the source container having the same
|
||||
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to the transferred elements
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(m*(I(n+m)+D(x.size())))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,
|
||||
<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise basic.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="observers">Observers</a></h4>
|
||||
|
||||
<p>Apart from standard <code>key_comp</code> and <code>value_comp</code>,
|
||||
@@ -1237,7 +1340,7 @@ Ranked indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 29th 2021</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -40,6 +40,7 @@ Key extraction
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#iterators">Iterators</a></li>
|
||||
<li><a href="#capacity">Capacity operations</a></li>
|
||||
@@ -316,10 +317,16 @@ plus the requirements for <code>std::list</code> specific list operations at
|
||||
|
||||
<span class=comment>// list operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>remove</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Predicate</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>remove_if</span><span class=special>(</span><span class=identifier>Predicate</span> <span class=identifier>pred</span><span class=special>);</span>
|
||||
@@ -450,6 +457,15 @@ index specifier. Instantiations are dependent on the following types:
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -875,56 +891,116 @@ The syntax and behavior of these operations exactly matches those
|
||||
of sequenced indices, but the associated complexity bounds differ in general.
|
||||
</p>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x);</code>
|
||||
<code>template<typename Index> void splice(const_iterator position,Index&& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.<br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements successfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(shl(end()-position,x.size()) + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index, and must be exactly <code>end()</code>
|
||||
if the source and destination containers are the same.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>splice</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x,iterator i);</code>
|
||||
<code>
|
||||
template<typename Index> std::pair<iterator,bool> splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator <code>x</code>.<br>
|
||||
<b>Effects:</b> Inserts the element pointed to by <code>i</code> before
|
||||
<code>position</code>: if insertion is successful, the element is erased from
|
||||
<code>x</code>. In the special case <code>&x==this</code>, no copy or
|
||||
deletion is performed, and the operation is always successful. If
|
||||
<code>position==i</code>, no operation is performed.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, <code>O(rel(position,i,i+1))</code>;
|
||||
otherwise <code>O(shl(end()-position,1) + I(n) + D(n))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, strong.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
If <code>get_allocator()!=x.get_allocator()</code>,
|
||||
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<ul>
|
||||
<li><b>(Same container)</b> if the source and destination containers are the same, repositions
|
||||
the element pointed to by <code>i</code> before <code>position</code> unless both
|
||||
iterators refer to the same element.</li>
|
||||
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>,
|
||||
transfers the node of the element referred to by <code>i</code> into the
|
||||
destination <code>multi_index_container</code> right before <code>position</code>
|
||||
if insertion is allowed by all other indices of the <code>multi_index_container</code>.</li>
|
||||
<li><b>(Destructive splice)</b> else, insertion of <code>*i</code> is tried before
|
||||
<code>position</code>; if the operation is successful, the element is erased from <code>x</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
|
||||
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to <code>*i</code>
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion (either through transfer or copy insertion)
|
||||
took place or the source and destination containers are the same.
|
||||
If <code>p.second</code> is <code>true</code>,
|
||||
<code>p.first</code> points to the inserted element or to <code>*i</code> if the
|
||||
source and destination containers are the same; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
<code>O(rel(position,i',i'+1))</code>, where <code>i'</code> is the projection
|
||||
of <code>i</code> into the index of <code>position</code>;
|
||||
otherwise, <code>O(shl(end()-position,1) + I(n) + D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise strong.<br>
|
||||
<b>Implementation note:</b> The destructive variant of this operation is provided
|
||||
for reasons of backwards compatibility with previous versions of this library where
|
||||
allocator equality was not required.
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name&</b> x,iterator first,iterator last);</code>
|
||||
<code>
|
||||
template<typename Index> void splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>first</code> and <code>last</code> are valid iterators of <code>x</code>.
|
||||
<code>last</code> is reachable from <code>first</code>. <code>position</code>
|
||||
is not in the range [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Effects:</b> For each element in the range [<code>first</code>,<code>last</code>),
|
||||
insertion is tried before <code>position</code>; if the operation is successful,
|
||||
the element is erased from <code>x</code>. In the special case
|
||||
<code>&x==this</code>, no copy or deletion is performed, and insertions are
|
||||
always successful.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>,
|
||||
<code>O(rel(position,first,last))</code>; otherwise
|
||||
<code>O(shl(end()-position,m) + m*I(n+m) + m*D(x.size()))</code>
|
||||
where <code>m</code> is the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
If <code>get_allocator()!=x.get_allocator()</code>,
|
||||
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index and does not point to any element in
|
||||
[<code>first</code>,<code>last</code>).
|
||||
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<ul>
|
||||
<li><b>(Same container)</b> if the source and destination containers are the same, repositions all the elements
|
||||
of [<code>first</code>,<code>last</code>), in this order, before <code>position</code>.
|
||||
</li>
|
||||
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>, then, for each node in
|
||||
[<code>first</code>,<code>last</code>), in this order, the node is transferred to the
|
||||
<code>multi_index_container</code> right before <code>position</code>
|
||||
if insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
<li><b>(Destructive splice)</b> else, for each element in [<code>first</code>,<code>last</code>), in this order,
|
||||
insertion is tried before <code>position</code>; if the operation is successful, the
|
||||
element is erased from <code>x</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> For any index in the source container having the same
|
||||
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to the transferred elements
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, <code>O(rel(position,first,last))</code>;
|
||||
else, if the source and destination containers are the same, <code>O(n)</code>;
|
||||
otherwise, <code>O(shl(end()-position,m) + m*(I(n+m) + D(x.size())))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise basic.<br>
|
||||
<b>Implementation note:</b> The destructive variant of this operation is provided
|
||||
for reasons of backwards compatibility with previous versions of this library where
|
||||
allocator equality was not required.
|
||||
</blockquote>
|
||||
|
||||
<code>void remove(const value_type& value);</code>
|
||||
@@ -973,20 +1049,22 @@ is the number of elements erased.<br>
|
||||
<code>void merge(index class name& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> induces a
|
||||
<b>Requires:</b>
|
||||
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
|
||||
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
|
||||
<code>std::less<value_type></code> induces a
|
||||
strict weak ordering over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to
|
||||
<code>std::less<value_type></code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). Elements
|
||||
successfully inserted are erased from <code>x</code>. The resulting sequence
|
||||
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). The resulting sequence
|
||||
is stable, i.e. equivalent elements of either container preserve their
|
||||
relative position. In the special case <code>&x==this</code>, no operation
|
||||
is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
Validity of iterators and references is preserved, except to elements removed
|
||||
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
@@ -996,19 +1074,20 @@ otherwise, basic.<br>
|
||||
<code>template <typename Compare> void merge(index class name& x,Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> induces a
|
||||
strict weak ordering over <code>value_type</code>.
|
||||
<b>Requires:</b>
|
||||
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
|
||||
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
|
||||
<code>Compare</code> induces a strict weak ordering over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to <code>comp</code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to <code>comp</code>).
|
||||
Elements successfully inserted are erased from <code>x</code>. The resulting
|
||||
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
|
||||
corresponding position of the index (according to <code>comp</code>). The resulting
|
||||
sequence is stable, i.e. equivalent elements of either container preserve
|
||||
their relative position. In the special case <code>&x==this</code>, no
|
||||
operation is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted according to <code>comp</code>.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
Validity of iterators and references is preserved, except to elements removed
|
||||
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
@@ -1160,9 +1239,9 @@ Key extraction
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 9th 2020</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2020 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -42,6 +42,7 @@ Hashed indices
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#rank_operations">Rank operations</a></li>
|
||||
<li><a href="#serialization">Serialization</a></li>
|
||||
</ul>
|
||||
@@ -473,6 +474,15 @@ These types are subject to the same requirements as specified for
|
||||
<a href="ord_indices.html#instantiation_types">ordered indices</a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="rank_operations">Rank operations</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -637,7 +647,7 @@ Hashed indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 29th 2021</p>
|
||||
<p>Revised August 14th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -40,6 +40,7 @@ Random access indices
|
||||
<ul>
|
||||
<li><a href="#complexity_signature">Complexity signature</a></li>
|
||||
<li><a href="#instantiation_types">Instantiation types</a></li>
|
||||
<li><a href="#types">Nested types</a></li>
|
||||
<li><a href="#constructors">Constructors, copy and assignment</a></li>
|
||||
<li><a href="#iterators">Iterators</a></li>
|
||||
<li><a href="#capacity">Capacity operations</a></li>
|
||||
@@ -299,10 +300,16 @@ most important differences are:
|
||||
|
||||
<span class=comment>// list operations:</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span><span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special><</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>></span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>i</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Index</span><span class=special>></span>
|
||||
<span class=keyword>void</span> <span class=identifier>splice</span><span class=special>(</span>
|
||||
<span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><b>index class name</b><span class=special>&</span> <span class=identifier>x</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
<span class=identifier>const_iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Index</span><span class=special>&&</span> <span class=identifier>x</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>first</span><span class=special>,</span>
|
||||
<span class=keyword>typename</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>remove_reference_t</span><span class=special><</span><span class=identifier>Index</span><span class=special>>::</span><span class=identifier>const_iterator</span> <span class=identifier>last</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>void</span> <span class=identifier>remove</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&</span> <span class=identifier>value</span><span class=special>);</span>
|
||||
<span class=keyword>template</span><span class=special><</span><span class=keyword>typename</span> <span class=identifier>Predicate</span><span class=special>></span> <span class=keyword>void</span> <span class=identifier>remove_if</span><span class=special>(</span><span class=identifier>Predicate</span> <span class=identifier>pred</span><span class=special>);</span>
|
||||
@@ -420,6 +427,15 @@ index specifier. Instantiations are dependent on the following types:
|
||||
<a href="indices.html#tag"><code>tag</code></a>.
|
||||
</p>
|
||||
|
||||
<h4><a name="types">Nested types</a></h4>
|
||||
|
||||
<code>iterator<br>
|
||||
const_iterator</code>
|
||||
|
||||
<blockquote>
|
||||
These types depend only on <code>node_type</code>.
|
||||
</blockquote>
|
||||
|
||||
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
|
||||
|
||||
<p>
|
||||
@@ -802,62 +818,122 @@ is rethrown.
|
||||
|
||||
<p>
|
||||
Sequenced indices provide the full set of list operations found in
|
||||
<code>std::list</code>; the semantics of these member functions, however,
|
||||
differ from that of <code>std::list</code> in some cases as insertions
|
||||
might not succeed due to banning by other indices. Similarly, the complexity
|
||||
<code>std::list</code>, extended in some cases such as <code>splice</code>;
|
||||
the semantics of these member functions, however,
|
||||
typically differs from that of <code>std::list</code> as insertions
|
||||
may not succeed due to banning by other indices. Similarly, the complexity
|
||||
of the operations may depend on the other indices belonging to the
|
||||
same <code>multi_index_container</code>.
|
||||
</p>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x);</code>
|
||||
<a name="splice"><code>template<typename Index> void splice(const_iterator position,Index&& x);</code></a>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>&x!=this</code>.<br>
|
||||
<b>Effects:</b> Inserts the contents of <code>x</code> before <code>position</code>,
|
||||
in the same order as they were in <code>x</code>. Those elements successfully
|
||||
inserted are erased from <code>x</code>.<br>
|
||||
<b>Complexity:</b> <code>O(x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> Basic.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index, and must be exactly <code>end()</code>
|
||||
if the source and destination containers are the same.<br>
|
||||
<b>Effects:</b>
|
||||
<blockquote><pre>
|
||||
<span class=identifier>splice</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
</pre></blockquote>
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name</b>& x,iterator i);</code>
|
||||
<code>
|
||||
template<typename Index> std::pair<iterator,bool> splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator i);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator <code>x</code>.<br>
|
||||
<b>Effects:</b> Inserts the element pointed to by <code>i</code> before
|
||||
<code>position</code>: if insertion is successful, the element is erased from
|
||||
<code>x</code>. In the special case <code>&x==this</code>, no copy or
|
||||
deletion is performed, and the operation is always successful. If
|
||||
<code>position==i</code>, no operation is performed.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(I(n) + D(n))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, strong.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
If <code>get_allocator()!=x.get_allocator()</code>,
|
||||
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index.
|
||||
<code>i</code> is a valid dereferenceable iterator of <code>x</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<ul>
|
||||
<li><b>(Same container)</b> if the source and destination containers are the same, repositions
|
||||
the element pointed to by <code>i</code> before <code>position</code> unless both
|
||||
iterators refer to the same element.</li>
|
||||
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>,
|
||||
transfers the node of the element referred to by <code>i</code> into the
|
||||
destination <code>multi_index_container</code> right before <code>position</code>
|
||||
if insertion is allowed by all other indices of the <code>multi_index_container</code>.</li>
|
||||
<li><b>(Destructive splice)</b> else, insertion of <code>*i</code> is tried before
|
||||
<code>position</code>; if the operation is successful, the element is erased from <code>x</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> If transfer succeeds, for any index in the source container
|
||||
having the same <code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to <code>*i</code>
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
|
||||
is <code>true</code> if and only if insertion (either through transfer or copy insertion)
|
||||
took place or the source and destination containers are the same.
|
||||
If <code>p.second</code> is <code>true</code>,
|
||||
<code>p.first</code> points to the inserted element or to <code>*i</code> if the
|
||||
source and destination containers are the same; otherwise, <code>p.first</code>
|
||||
points to an element that caused the insertion to be banned. Note that more than
|
||||
one element can be causing insertion not to be allowed.<br>
|
||||
<b>Complexity:</b> If the source and destination containers are the same,
|
||||
constant; otherwise, <code>O(I(n)+D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise strong.<br>
|
||||
<b>Implementation note:</b> The destructive variant of this operation is provided
|
||||
for reasons of backwards compatibility with previous versions of this library where
|
||||
allocator equality was not required.
|
||||
</blockquote>
|
||||
|
||||
<code>void splice(iterator position,<b>index class name&</b> x,iterator first,iterator last);</code>
|
||||
<code>
|
||||
template<typename Index> void splice(<br>
|
||||
const_iterator position,Index&& x,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator first,<br>
|
||||
typename std::remove_reference_t<Index>::const_iterator last);
|
||||
</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
|
||||
<code>first</code> and <code>last</code> are valid iterators of <code>x</code>.
|
||||
<code>last</code> is reachable from <code>first</code>. <code>position</code>
|
||||
is not in the range [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Effects:</b> For each element in the range [<code>first</code>,<code>last</code>),
|
||||
insertion is tried before <code>position</code>; if the operation is successful,
|
||||
the element is erased from <code>x</code>. In the special case
|
||||
<code>&x==this</code>, no copy or deletion is performed, and insertions are
|
||||
always successful.<br>
|
||||
<b>Postconditions:</b> If <code>&x==this</code>, no iterator or reference
|
||||
is invalidated.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(m*I(n+m) + m*D(x.size()))</code> where <code>m</code> is the number
|
||||
of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
otherwise, basic.<br>
|
||||
<b>Requires:</b> <code>x</code> is a non-const reference to an index of a
|
||||
<a href="multi_index_container.html#node_type">node-compatible</a>
|
||||
<code>multi_index_container</code>.
|
||||
If <code>get_allocator()!=x.get_allocator()</code>,
|
||||
<code>value_type</code> must be <code>CopyInsertable</code> into the destination
|
||||
<code>multi_index_container</code>.
|
||||
<code>position</code> is a valid iterator of the index and does not point to any element in
|
||||
[<code>first</code>,<code>last</code>).
|
||||
[<code>first</code>,<code>last</code>) is a valid range of <code>x</code>.<br>
|
||||
<b>Effects:</b>
|
||||
<ul>
|
||||
<li><b>(Same container)</b> if the source and destination containers are the same, repositions all the elements
|
||||
of [<code>first</code>,<code>last</code>), in this order, before <code>position</code>.
|
||||
</li>
|
||||
<li><b>(Transfer splice)</b> else, if <code>get_allocator()==x.get_allocator()</code>, then, for each node in
|
||||
[<code>first</code>,<code>last</code>), in this order, the node is transferred to the
|
||||
<code>multi_index_container</code> right before <code>position</code>
|
||||
if insertion is allowed by all other indices of the
|
||||
<code>multi_index_container</code>.</li>
|
||||
<li><b>(Destructive splice)</b> else, for each element in [<code>first</code>,<code>last</code>), in this order,
|
||||
insertion is tried before <code>position</code>; if the operation is successful, the
|
||||
element is erased from <code>x</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<b>Postconditions:</b> For any index in the source container having the same
|
||||
<code>iterator</code>/<code>const_iterator</code> types as the corresponding
|
||||
index in the destination container, iterators referring to the transferred elements
|
||||
remain valid and behave as iterators of the destination index.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; else, if
|
||||
the source and destination containers are the same, <code>O(m)</code>;
|
||||
otherwise, <code>O(m*(I(n+m)+D(x.size())))</code>, where
|
||||
<code>m</code> is the number of elements in [<code>first</code>,<code>last</code>).<br>
|
||||
<b>Exception safety:</b> If the source and destination containers are the same,
|
||||
<code>nothrow</code>; otherwise basic.<br>
|
||||
<b>Implementation note:</b> The destructive variant of this operation is provided
|
||||
for reasons of backwards compatibility with previous versions of this library where
|
||||
allocator equality was not required.
|
||||
</blockquote>
|
||||
|
||||
<code>void remove(const value_type& value);</code>
|
||||
@@ -906,20 +982,22 @@ is the number of elements erased.<br>
|
||||
<code>void merge(index class name& x);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>std::less<value_type></code> induces a
|
||||
<b>Requires:</b>
|
||||
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
|
||||
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
|
||||
<code>std::less<value_type></code> induces a
|
||||
strict weak ordering over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to
|
||||
<code>std::less<value_type></code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). Elements
|
||||
successfully inserted are erased from <code>x</code>. The resulting sequence
|
||||
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
|
||||
corresponding position of the index (according to the order). The resulting sequence
|
||||
is stable, i.e. equivalent elements of either container preserve their
|
||||
relative position. In the special case <code>&x==this</code>, no operation
|
||||
is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
Validity of iterators and references is preserved, except to elements removed
|
||||
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
@@ -929,19 +1007,20 @@ otherwise, basic.<br>
|
||||
<code>template <typename Compare> void merge(index class name& x,Compare comp);</code>
|
||||
|
||||
<blockquote>
|
||||
<b>Requires:</b> <code>Compare</code> induces a
|
||||
strict weak ordering over <code>value_type</code>.
|
||||
<b>Requires:</b>
|
||||
Either <code>get_allocator()==x.get_allocator()</code> or <code>value_type</code>
|
||||
is <code>CopyInsertable</code> into the <code>multi_index_container</code>.
|
||||
<code>Compare</code> induces a strict weak ordering over <code>value_type</code>.
|
||||
Both the index and <code>x</code> are sorted according to <code>comp</code>.<br>
|
||||
<b>Effects:</b> Attempts to insert every element of <code>x</code> into the
|
||||
corresponding position of the index (according to <code>comp</code>).
|
||||
Elements successfully inserted are erased from <code>x</code>. The resulting
|
||||
<b>Effects:</b> Attempts to splice every element of <code>x</code> into the
|
||||
corresponding position of the index (according to <code>comp</code>). The resulting
|
||||
sequence is stable, i.e. equivalent elements of either container preserve
|
||||
their relative position. In the special case <code>&x==this</code>, no
|
||||
operation is performed.<br>
|
||||
<b>Postconditions:</b> Elements in the index and remaining elements in
|
||||
<code>x</code> are sorted according to <code>comp</code>.
|
||||
Validity of iterators to the index and of non-erased elements of <code>x</code>
|
||||
references is preserved.<br>
|
||||
Validity of iterators and references is preserved, except to elements removed
|
||||
from <code>x</code> if <code>get_allocator()!=x.get_allocator()</code>.<br>
|
||||
<b>Complexity:</b> If <code>&x==this</code>, constant; otherwise
|
||||
<code>O(n + x.size()*I(n+x.size()) + x.size()*D(x.size()))</code>.<br>
|
||||
<b>Exception safety:</b> If <code>&x==this</code>, <code>nothrow</code>;
|
||||
@@ -1095,9 +1174,9 @@ Random access indices
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 9th 2020</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2020 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -72,6 +72,34 @@ Acknowledgements
|
||||
<li>Added <code>contains</code> to key-based indices
|
||||
(<a href="https://github.com/boostorg/multi_index/issues/35">issue #35</a>).
|
||||
</li>
|
||||
<li>Added <code>merge</code> operations to key-based indices. The functionality goes beyond
|
||||
the standard specification for (unordered) associative containers in a number of ways,
|
||||
most notably:
|
||||
<ul>
|
||||
<li>The source index can be of any type, including non key-based indices.</li>
|
||||
<li>Partial merge is provided: for instance, <code>x.merge(y,first,last)</code>
|
||||
merges only the elements of <code>y</code> within [<code>first</code>,<code>last</code>).
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Previous versions of <code>splice</code> for sequenced and random access indices
|
||||
were destructive, i.e. elements were copy-inserted into the destination and then erased
|
||||
from the source. Now, <code>splice</code> is based on node transfer much as <code>merge</code>
|
||||
in key-based indices, and has been similarly extended to accept source indices of any type:
|
||||
in fact, <code>splice</code> can be regarded as a frontend to the same functionality
|
||||
provided by <code>merge</code> in key-based indices. For reasons of backwards compatibility,
|
||||
the destructive behavior of <code>splice</code> has been retained in the case that the
|
||||
source and destination containers have unequal allocators.
|
||||
</li>
|
||||
<li>The fact has been documented that index iterator types do only depend on <code>node_type</code>,
|
||||
(except for hashed indices, where uniqueness/non-uniqueness is also a dependency). This has
|
||||
implications on the validity of iterators to elements transferred by <code>merge</code> or
|
||||
<code>splice</code>. This property is a variant of what has been called
|
||||
<a href="https://wg21.link/n2980">SCARY iterators</a> in the C++ standard mailing lists.
|
||||
SCARYness is currently (August 2021) not mandated for standard containers.
|
||||
</li>
|
||||
<li>Iterator SCARYness is now also preserved in <a href="tutorial/debug.html#safe_mode">safe mode</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -88,7 +116,7 @@ Acknowledgements
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
Added <a href="tutorial/basics.html#node_handling">node extraction and insertion</a>
|
||||
Added <a href="tutorial/indices.html#node_handling">node extraction and insertion</a>
|
||||
following the analogous interface of associative containers as introduced in C++17.
|
||||
This feature has also been extended to non key-based indices, in contrast to C++
|
||||
standard library sequence containers, which do not provide such functionality.
|
||||
@@ -695,7 +723,7 @@ Acknowledgements
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 29th 2021</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -62,7 +62,6 @@ Index types
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#projection">Projection of iterators</a></li>
|
||||
<li><a href="#node_handling">Node handling operations</a></li>
|
||||
<li><a href="#complexity">Complexity and exception safety</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -1217,72 +1216,6 @@ When provided, <code>project</code> can also be used with
|
||||
<a href="#tagging">tags</a>.
|
||||
</p>
|
||||
|
||||
<h2><a name="node_handling">Node handling operations</a></h2>
|
||||
|
||||
<p>
|
||||
Using direct node manipulation, elements can be passed between
|
||||
<code>multi_index_container</code>s without actually copying them:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// move an employee to the retiree archive</span>
|
||||
<span class=keyword>void</span> <span class=identifier>move_to_retirement</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>archive</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=comment>// extract the employee with given SS number to a node handle</span>
|
||||
<span class=identifier>employee_set_by_ssn</span><span class=special>::</span><span class=identifier>node_type</span> <span class=identifier>node</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>ssn</span><span class=special>>().</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>if</span><span class=special>(!</span><span class=identifier>node</span><span class=special>.</span><span class=identifier>empty</span><span class=special>()){</span> <span class=comment>// employee found
|
||||
// re-insert into archive (note the use of std::move)</span>
|
||||
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>node</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
In the example, the internal node is transferred as-is from <code>es</code> to <code>archive</code>,
|
||||
which is more efficient than erasing from the source and recreating in destination.
|
||||
<code>node_type</code> is a move-only class used to pass nodes around, and its interface follows
|
||||
that of the <a href="https://en.cppreference.com/w/cpp/container/node_handle">homonym type</a>
|
||||
for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
|
||||
and insertion operations for all index types, including sequenced ones (by contrast,
|
||||
<code>std::list</code> does not have such features):
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</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=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=special>></span>
|
||||
<span class=special>></span> <span class=identifier>src</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</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=identifier>ordered_non_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=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>dst</span><span class=special>;</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=comment>// transfer even numbers from src to dst</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>;){</span>
|
||||
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>)</span> <span class=identifier>dst</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>first</span><span class=special>++));</span>
|
||||
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Note that <code>src</code> and <code>dst</code> are of different types,
|
||||
yet transfer is possible. Two <code>multi_index_container</code>s are
|
||||
node-compatible (that is, they use the same <code>node_type</code>) if
|
||||
they have the same element and allocator types and their respective indices match
|
||||
one by one without regard to whether they are unique or non-unique or to
|
||||
their particular configuration parameters: they are both ordered, or
|
||||
both sequenced, etc.
|
||||
</p>
|
||||
<h2><a name="complexity">Complexity and exception safety</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -1317,9 +1250,9 @@ Index types
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised May 9th 2020</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2020 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
|
||||
|
||||
@@ -55,6 +55,7 @@ Key extraction
|
||||
</li>
|
||||
<li><a href="#rearrange">Index rearranging</a></li>
|
||||
<li><a href="#iterator_to"><code>iterator_to</code></a></li>
|
||||
<li><a href="#node_handling">Node handling operations</a></li>
|
||||
<li><a href="#ordered_node_compression">Ordered indices node compression</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -282,7 +283,7 @@ determining whether a hashed index is preferred over an ordered one.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Hashed indices replicate the interface as <code>std::unordered_set</code> and
|
||||
Hashed indices replicate the interface of <code>std::unordered_set</code> and
|
||||
<code>std::unordered_multiset</code>, with only minor differences where required
|
||||
by the general constraints of <code>multi_index_container</code>s, and provide
|
||||
additional useful capabilities like in-place updating of elements.
|
||||
@@ -774,6 +775,113 @@ in scenarios where access via iterators is not suitable or desireable:
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h2><a name="node_handling">Node handling operations</a></h2>
|
||||
|
||||
<p>
|
||||
Using direct node manipulation, elements can be passed between
|
||||
<code>multi_index_container</code>s without actually copying them:
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// move an employee to the retiree archive</span>
|
||||
<span class=keyword>void</span> <span class=identifier>move_to_retirement</span><span class=special>(</span><span class=keyword>int</span> <span class=identifier>ssnumber</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>archive</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=comment>// assume employee_set has an index on SS number(not shown before)</span>
|
||||
<span class=comment>// extract the employee with given SS number to a node handle</span>
|
||||
<span class=identifier>employee_set_by_ssn</span><span class=special>::</span><span class=identifier>node_type</span> <span class=identifier>node</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>ssn</span><span class=special>>().</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>ssnumber</span><span class=special>);</span>
|
||||
|
||||
<span class=keyword>if</span><span class=special>(!</span><span class=identifier>node</span><span class=special>.</span><span class=identifier>empty</span><span class=special>()){</span> <span class=comment>// employee found
|
||||
// re-insert into archive (note the use of std::move)</span>
|
||||
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>move</span><span class=special>(</span><span class=identifier>node</span><span class=special>));</span>
|
||||
<span class=special>}</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
In the example, the internal node is transferred as-is from <code>es</code> to <code>archive</code>,
|
||||
which is more efficient than erasing from the source and recreating in destination.
|
||||
<code>node_type</code> is a move-only class used to pass nodes around, and its interface follows
|
||||
that of the <a href="https://en.cppreference.com/w/cpp/container/node_handle">homonym type</a>
|
||||
for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
|
||||
and insertion operations for all index types, including sequenced ones (by contrast,
|
||||
<code>std::list</code> does not have such features):
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</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=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=special>></span>
|
||||
<span class=special>></span> <span class=identifier>src</span><span class=special>;</span>
|
||||
|
||||
<span class=identifier>multi_index_container</span><span class=special><</span>
|
||||
<span class=keyword>int</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=identifier>ordered_non_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=identifier>std</span><span class=special>::</span><span class=identifier>greater</span><span class=special><</span><span class=keyword>int</span><span class=special>></span> <span class=special>></span>
|
||||
<span class=special>></span>
|
||||
<span class=special>></span> <span class=identifier>dst</span><span class=special>;</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=comment>// transfer even numbers from src to dst</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>;){</span>
|
||||
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>)</span> <span class=identifier>dst</span><span class=special>.</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>extract</span><span class=special>(</span><span class=identifier>first</span><span class=special>++));</span>
|
||||
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Note that <code>src</code> and <code>dst</code> are of different types,
|
||||
yet transfer is possible. Two <code>multi_index_container</code>s are
|
||||
node-compatible (that is, they use the same <code>node_type</code>) if
|
||||
they have the same element and allocator types and their respective indices match
|
||||
one by one without regard to whether they are unique or non-unique or to
|
||||
their particular configuration parameters: they are both ordered, or
|
||||
both sequenced, etc.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Alternatively, direct node transfer between two containers can be done without
|
||||
keeping intervening <code>node_type</code>s thanks to <code>merge</code> (key-based
|
||||
indices) and <code>splice</code> (non key-based indices).
|
||||
</p>
|
||||
|
||||
<blockquote><pre>
|
||||
<span class=comment>// move older employees to retirement</span>
|
||||
<span class=keyword>void</span> <span class=identifier>move_to_retirement_by_age</span><span class=special>(
|
||||
</span><span class=keyword>int</span> <span class=identifier>max_age</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>es</span><span class=special>,</span><span class=identifier>employee_set</span><span class=special>&</span> <span class=identifier>archive</span><span class=special>)</span>
|
||||
<span class=special>{</span>
|
||||
<span class=comment>// assume employee_set has an index on age (not shown before)</span>
|
||||
<span class=identifier>employee_set_by_age</span><span class=special>&</span> <span class=identifier>ea</span><span class=special>=</span><span class=identifier>es</span><span class=special>.</span><span class=identifier>get</span><span class=special><</span><span class=identifier>age</span><span class=special>>();</span>
|
||||
|
||||
<span class=comment>// archive employees with age>max_age</span>
|
||||
<span class=identifier>archive</span><span class=special>.</span><span class=identifier>merge</span><span class=special>(</span><span class=identifier>ea</span><span class=special>,</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>upper_bound</span><span class=special>(</span><span class=identifier>max_age</span><span class=special>),</span><span class=identifier>ea</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
|
||||
<span class=special>}</span>
|
||||
|
||||
<span class=special>...</span>
|
||||
|
||||
<span class=comment>// transfer even numbers from src to dst</span>
|
||||
<span class=keyword>for</span><span class=special>(</span><span class=keyword>auto</span> <span class=identifier>first</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>last</span><span class=special>=</span><span class=identifier>src</span><span class=special>.</span><span class=identifier>end</span><span class=special>();</span><span class=identifier>first</span><span class=special>!=</span><span class=identifier>last</span><span class=special>;){</span>
|
||||
<span class=keyword>if</span><span class=special>(*</span><span class=identifier>first</span><span class=special>%</span><span class=number>2</span><span class=special>==</span><span class=number>0</span><span class=special>)</span> <span class=identifier>dst</span><span class=special>.</span><span class=identifier>splice</span><span class=special>(</span><span class=identifier>dst</span><span class=special>.</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>src</span><span class=special>,</span><span class=identifier>first</span><span class=special>++);</span>
|
||||
<span class=keyword>else</span> <span class=special>++</span><span class=identifier>first</span><span class=special>;</span>
|
||||
<span class=special>}</span>
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
There are overloads of <code>merge</code>/<code>splice</code> for transferring a single element,
|
||||
a range between two iterators and an entire container: for further details, consult
|
||||
for instance the reference for <a href="../reference/ord_indices.html#merge">ordered indices</a> and for
|
||||
<a href="../reference/seq_indices.html#splice">sequenced indices</a>
|
||||
(the rest of indices provide one interface or the other).
|
||||
Please note that sequenced and random access indices do also have an operation called <code>merge</code>,
|
||||
but this follows the specification of <code>std::list::merge</code>, which has a somewhat
|
||||
different behavior (source and destination are required to be ordered by the same criterion). This is
|
||||
a rather confusing naming issue that Boost.MultiIndex simply inherits from the C++ standard.
|
||||
</p>
|
||||
|
||||
<h2><a name="ordered_node_compression">Ordered indices node compression</a></h2>
|
||||
|
||||
<p>
|
||||
@@ -821,7 +929,7 @@ Key extraction
|
||||
|
||||
<br>
|
||||
|
||||
<p>Revised July 29th 2021</p>
|
||||
<p>Revised August 16th 2021</p>
|
||||
|
||||
<p>© Copyright 2003-2021 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
Reference in New Issue
Block a user