merged [85001], [85004], [85005], [85016], [85017], [85018], [85022], [85028], [85099] and [85100] from trunk

[SVN r85146]
This commit is contained in:
Joaquín M López Muñoz 2013-07-24 07:52:40 +00:00
parent d2f0ef79a2
commit 0bc802ad7d
26 changed files with 2699 additions and 1877 deletions

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,6 @@ principle driving the current internal design of <code>multi_index_container</co
<li><a href="#constraints">Constraints</a></li>
<li><a href="#user_defined_indices">User-defined indices</a></li>
<li><a href="#indexed_maps">Indexed maps</a></li>
<li><a href="#move_semantics">Move semantics</a></li>
</ul>
<h2><a name="ranked_indices">Ranked indices</a></h2>
@ -187,31 +186,6 @@ a careful study when designing the interface of a potential
indexed map.
</p>
<h2><a name="move_semantics">Move semantics</a></h2>
<p>
Andrei Alexandrescu introduced a technique for simulating move
constructors called Mojo (see his article in C/C++ User Journal
<a href="http://www.cuj.com/documents/s=8246/cujcexp2102alexandr/">
"Generic&lt;Programming>: Move Constructors"</a>.) Move semantics
alleviates the computational load involved in the creation and copying
of temporary objects, specially for heavy classes as
<code>multi_index_container</code>s are. David Abrahams and Gary Powell provide
an alternative implementation of move semantics in their paper
<a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1610.html">
"Clarification of Initialization of Class Objects by rvalues"</a> for
the C++ Evolution Working Group.
</p>
<p>
Adding move semantics to <code>multi_index_container</code> is particularly
beneficial when the container is used as an internal building block in other
libraries (vg. relational database frameworks), enabling the efficient
development of functions returning <code>multi_index_container</code>s. Without support
for move semantics, this scheme is impractical and less elegant syntaxes
should be resorted to.
</p>
<hr>
<div class="prev_link"><a href="tests.html"><img src="prev.gif" alt="tests" border="0"><br>
@ -226,9 +200,9 @@ Release notes
<br>
<p>Revised July 5th 2007</p>
<p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -99,6 +99,8 @@ their associated <a href="#hash_indices">hashed index</a> classes.
<code>"boost/multi_index/hashed_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -170,11 +172,8 @@ explanations on their acceptable type values.
<p>
A hashed index provides fast retrieval of elements of a <code>multi_index_container</code>
through hashing tecnhiques. The interface and semantics of hashed indices are modeled according
to the proposal for unordered associative containers given in the C++
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf">Proposed
Draft Tecnhical Report on Standard Library Extensions</a>, also known as TR1. A hashed
index is particularized according to a given
through hashing tecnhiques.
A hashed index is particularized according to a given
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
that retrieves keys from elements of <code>multi_index_container</code>, a <code>Hash</code>
function object which returns hash values for the keys and a binary predicate <code>Pred</code>
@ -190,13 +189,14 @@ together, with minor differences explicitly stated when they exist.
</p>
<p>
Except where noted, hashed indices (both unique and non-unique) are models of
<code>Unordered Associative Container</code>, in the spirit of
<code>std::tr1::unordered_set</code>s. Validity of iterators and references to
Except where noted or if the corresponding interface does not exist, hashed indices
(both unique and non-unique) satisfy the C++ requirements for undordered associative
containers at <b>[unord.req]</b> (supporting unique and equivalent keys, respectively.)
Validity of iterators and references to
elements is preserved in all cases. Occasionally, the exception safety guarantees provided
are actually stronger than required by the extension draft. We only provide descriptions
of those types and operations that are either not present in the concepts modeled or
do not exactly conform to the requirements for unordered associative containers.
are actually stronger than required by the standard. We only provide descriptions of
those types and operations that do not exactly conform to or are not mandated by the standard
requirements.
</p>
<blockquote><pre>
@ -236,6 +236,7 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=comment>// construct/destroy/copy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -259,16 +260,25 @@ do not exactly conform to the requirements for unordered associative containers.
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</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=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
@ -397,13 +407,11 @@ following types:
which determines the mechanism for extracting a key from <code>Value</code>,
must be a model of <a href="key_extraction.html#key_extractors">
<code>Key Extractor</code></a> from <code>Value</code>. <code>Hash</code> is a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary Function</code></a>
<code>CopyConstructible</code>unary function object
taking a single argument of type <code>KeyFromValue::result_type</code> and returning a
value of type <code>std::size_t</code> in the range
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>.
<code>Pred</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> inducing an equivalence relation
<code>Pred</code> is a <code>CopyConstructible</code> binary predicate inducing an equivalence relation
on elements of <code>KeyFromValue::result_type</code>. It is required that
the <code>Hash</code> object return the same value for keys
equivalent under <code>Pred</code>.
@ -425,9 +433,7 @@ local_iterator<br>
const_local_iterator</code>
<blockquote>
These types are models of
<a href="http://www.sgi.com/tech/stl/ForwardIterator.html"><code>Forward
Iterator</code></a>.
These types are forward iterators.
</blockquote>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
@ -451,6 +457,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
@ -465,9 +483,64 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the 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>
<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 took place. On successful insertion,
<code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
iterator emplace_hint(iterator position, Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the 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>
<code>position</code> is used as a hint to improve the efficiency of the
operation.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator 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> <code>O(H(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@ -485,10 +558,16 @@ one element can be causing insertion not to be allowed.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>iterator insert(iterator position,const value_type&amp; x);</code>
<code>iterator insert(iterator position,const value_type&amp; x);</code><br>
<code>iterator insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@ -511,24 +590,38 @@ allowed.<br>
void insert(InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
<code>value_type</code> is
<code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
<span class=keyword>while</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=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
</pre></blockquote>
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it into the <code>multi_index_container</code>
to which this 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>
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where
<code>m</code> is the number of elements in [<code>first</code>,
<code>last</code>).<br>
<b>Exception safety:</b> Basic.<br>
</blockquote>
<code>void insert(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
@ -565,11 +658,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if, for the value <code>x</code>
@ -594,9 +690,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -610,8 +705,8 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
</ul>
If the rearrangement fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds. If the key of the modified value is equivalent to that of the original
value, the position of the element does not change.<br>
operation succeeds. If the key of the modified value is equivalent to that of the
original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
@ -624,9 +719,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
@ -644,8 +738,9 @@ all the indices of the <code>multi_index_container</code>. Rearrangement is succ
If the rearrangement fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below. If the key of the modified value
is equivalent to that of the original value, the position of the element does not change.<br>
the element is erased under the conditions described below.
If the key of the modified value is equivalent to that of the
original value, the position of the element does not change.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
otherwise.<br>
<b>Complexity:</b> <code>O(M(n))</code>.<br>
@ -662,9 +757,8 @@ is rethrown.
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
from <code>value_type</code>. <code>mod</code> is a
unary function object accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
@ -679,14 +773,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
from <code>value_type</code>. <code>mod</code> and <code>back</code>
are unary function objects accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br>
pointed to by <code>position</code>, restores <code>k</code> to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
@ -713,7 +806,7 @@ the index.<br>
<p>
Hashed indices provide the full lookup functionality required by
unordered associative containers, namely <code>find</code>,
<b>[unord.req]</b>, namely <code>find</code>,
<code>count</code>, and <code>equal_range</code>. Additionally,
these member functions are templatized to allow for non-standard
arguments, so extending the types of search operations allowed.
@ -724,9 +817,8 @@ functions is defined by the following concept.
<p>
Consider a pair (<code>Hash</code>, <code>Pred</code>) where
<code>Hash</code> is a hash functor over values of type <code>Key</code>
and <code>Pred</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> inducing an equivalence relation
and <code>Pred</code> is a binary predicate
inducing an equivalence relation
on <code>Key</code>, with the additional constraint that equivalent
keys have the same hash value.
A triplet of types (<code>CompatibleKey</code>, <code>CompatibleHash</code>,
@ -735,13 +827,9 @@ of (<code>Hash</code>, <code>Pred</code>) if
<ol>
<li><code>CompatibleHash</code> is a hash functor on values of
type <code>CompatibleKey</code>,</li>
<li><code>CompatiblePred</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>Key</code>,
<li><code>CompatiblePred</code> is a binary predicate over (<code>Key</code>,
<code>CompatibleKey</code>),</li>
<li><code>CompatiblePred</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
<li><code>CompatiblePred</code> is a binary predicate over (<code>CompatibleKey</code>,
<code>Key</code>),</li>
<li>if <code>c_eq(ck,k1)</code> then <code>c_eq(k1,ck)</code>,</li>
<li>if <code>c_eq(ck,k1)</code> and <code>eq(k1,k2)</code> then
@ -981,9 +1069,9 @@ Sequenced indices
<br>
<p>Revised July 21st 2009</p>
<p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -105,12 +105,13 @@ The last two primitives deserve some further explanation: in order to
guarantee the invariants associated to each index (e.g. some definite
ordering,) elements of a <code>multi_index_container</code> are not mutable.
To overcome this restriction, indices expose member functions
for updating and modifying, which allow for the mutation of elements
for replacement and modification which allow for the mutation of elements
in a controlled fashion. Immutability of elements does not significantly
impact the interface of ordered indices, as it is based upon that of
<code>std::set</code> and <code>std:multiset</code>, and these containers
impact the interfaces of ordered and hashed indices, as they are based upon
those of associative and unordered associative containers, respectively,
and these containers
also have non-mutable elements; but it may come as a surprise when dealing
with sequenced indices, which are designed upon the functionality provided
with sequenced and random access indices, which are designed upon the functionality provided
by <code>std::list</code>.
</p>
@ -120,11 +121,9 @@ they are wrapped as appropriate by each index (for instance, ordered indices
provide a set-like suite of insertion member functions, whereas sequenced
and random access indices have <code>push_back</code> and <code>push_front</code>
operations.) Boost.MultiIndex poses no particular conditions on
the interface of indices, save that they must model
<a href="http://www.sgi.com/tech/stl/Container.html">
<code>Container</code></a> (without the requirement of being
<a href="http://www.sgi.com/tech/stl/Assignable.html">
<code>Assignable</code></a>.)
the interface of indices, although each index provided satisfy the C++ requirements for
standard containers to the maximum extent possible within the conceptual framework
of the library.
</p>
<h2><a name="complexity_signature">Complexity signature</a></h2>
@ -333,10 +332,7 @@ reference</a>.
The following concept is used by the rearrange facilities of non key-based
indices. Given an index <code>i</code> of type <code>Index</code>, a <i>view
of <code>i</code></i> is any range [<code>first</code>,<code>last</code>)
where <code>first</code> and <code>last</code> are objects of a type
<code>Iterator</code> modelling
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> such that
where <code>first</code> and <code>last</code> are input iterators such that
<ol>
<li>the associated value type of <code>Iterator</code> is convertible
to <code>const Index::value_type&amp;</code>
@ -383,9 +379,9 @@ Ordered indices
<br>
<p>Revised July 21st 2009</p>
<p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -57,10 +57,8 @@ Compiler specifics
<ul>
<li><a href="#const_mem_fun">Class template <code>const_mem_fun</code></a></li>
<li><a href="#mem_fun">Class template <code>mem_fun</code></a></li>
<li><a href="#const_mem_fun_explicit">Class template <code>const_mem_fun_explicit</code></a></li>
<li><a href="#mem_fun_explicit">Class template <code>mem_fun_explicit</code></a></li>
<li><a href="#boost_multi_index_const_mem_fun">Macro <code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a></li>
<li><a href="#boost_multi_index_mem_fun">Macro <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
<li><a href="#const_mem_fun_explicit">Class templates <code>const_mem_fun_explicit</code> and <code>mem_fun_explicit</code></a></li>
<li><a href="#boost_multi_index_const_mem_fun">Macros <code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code> and <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></li>
</ul>
</li>
<li><a href="#global_fun_synopsis">Header
@ -108,7 +106,7 @@ Compiler specifics
Key extraction classes are used by
<a href="indices.html#key_based_indices">key-based indices</a> to
obtain the indexing keys from the elements of a <code>multi_index_container</code>.
An <a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>
A <code>CopyConstructible</code> and <code>CopyAssignable</code>
class <code>KeyFromValue</code> is said to be a key extractor from a
type <code>Type</code> if
<ol>
@ -144,16 +142,8 @@ Boost.MultiIndex provides six general-purpose key extractors:
<li><a href="#const_mem_fun"><code>const_mem_fun</code></a>,</li>
<li><a href="#mem_fun"><code>mem_fun</code></a>,</li>
<li><a href="#global_fun"><code>global_fun</code></a> and</li>
<li><a href="#composite_key"><code>composite_key</code></a>,</li>
<li><a href="#composite_key"><code>composite_key</code></a>.</li>
</ul>
plus replacements for some of them:
<ul>
<li><a href="#member_offset"><code>member_offset</code></a>,</li>
<li><a href="#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a> and</li>
<li><a href="#mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
</ul>
that workaround some deficiencies in the support for non-type template parameters
by certain compilers.
</p>
<h3><a name="chained_pointers">Chained pointers</a></h3>
@ -310,7 +300,7 @@ type to <code>Type</code>.<br>
<span class=keyword>struct</span> <span class=identifier>member</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>OffsetOfMember</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>member_offset</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>member_offset</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_MEMBER</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberName</span><span class=special>)</span> <b>implementation defined</b>
@ -399,53 +389,10 @@ type to <code>Type</code>.<br>
<h3><a name="member_offset">Class template <code>member_offset</code></a></h3>
<p>
Some compilers do not properly support pointers to members as non-type
template arguments. The following have been confirmed to have bugs in
this respect:
<ul>
<li>MSVC++ 6.0 (see
<a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045">Microsoft
Knowledge Base article #249045</a>),</li>
<li>MSVC++ 7.0 (not officially confirmed by Microsoft),</li>
<li>Intel C++ 7.0/7.1 for Windows (support issue #207321),</li>
<li>VisualAge 6.0 for AIX (internal defect #288539.)</li>
</ul>
In this situation, <code>member_offset</code> provides an
alternative to <a href="#member"><code>member</code></a> accepting offsets
instead of pointers to members. Please note that the use of
<code>offsetof</code> on non-POD types is forbidden by the standard;
luckily enough, most compilers accept it nevertheless, so
<code>member_offset</code> serves as a workaround for most practical purposes.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>OffsetOfMember</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>member_offset</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>Type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span> <span class=comment>// only provided if Type is non-const</span>
<span class=keyword>const</span> <span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>As an example of use, given the class</p>
<blockquote><pre>
<span class=keyword>class</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>x</span><span class=special>;</span>
<span class=special>}</span>
</pre></blockquote>
<p>
the instantiation <code>member&lt;A,int,&amp;A::x></code> can be simulated then
as <code>member_offset&lt;A,int,offsetof(A,x)></code>.
<code>member_offset</code> was designed to overcome limitations of some legacy
compilers and its use is currently deprecated. Refer to a
<a href="http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/reference/key_extraction.html#member_offset">former version</a>
of Boost.MultiIndex for further information.
</p>
<h3><a name="boost_multi_index_member">Macro <code>BOOST_MULTI_INDEX_MEMBER</code></a></h3>
@ -455,27 +402,10 @@ as <code>member_offset&lt;A,int,offsetof(A,x)></code>.
</pre></blockquote>
<p>
This macro is provided as an aid for using <code>member</code> and
<code>member_offset</code> when writing cross-platform code. In the usual cases,
it expands to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>member_offset</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>offsetof</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>MemberName</span><span class=special>)&gt;</span>
</pre></blockquote>
<p>
if the <a href="../../../../libs/config/config.htm">Boost Configuration Library</a>
defect macro <code>BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS</code>
is defined.
This macro was designed as a portability mechanism for legacy compilers where <code>member</code>
could not be supported.
As such it is no longer needed in modern environments, though some users might still prefer it
to plain <code>member</code> because it provides a slightly more concise syntax.
</p>
<h2>
@ -498,13 +428,13 @@ is defined.
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=preprocessor>#define</span> <span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span> <span class=special>\</span>
<b>implementation defined</b>
@ -646,135 +576,28 @@ object chained-pointed to by <code>x</code>.
<b>Returns:</b> <code>(x.get().*PtrToMemberFunction)()</code>.
</blockquote>
<h3><a name="const_mem_fun_explicit">Class template <code>const_mem_fun_explicit</code></a></h3>
<h3><a name="const_mem_fun_explicit">Class templates <code>const_mem_fun_explicit</code> and <code>mem_fun_explicit</code></a></h3>
<p>
MSVC++ 6.0 do not properly support pointers to constant member functions as non-type
template parameters, thus <a href="#const_mem_fun"><code>const_mem_fun</code></a> cannot be
used in this compiler. A simple workaround consists in specifying the <i>type</i> of
these pointers as an additional template parameter.
These extractors were provided as a workaround for MSVC++ 6.0 and are now deprecated.
Refer to a
<a href="http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/reference/key_extraction.html#const_mem_fun_explicit">former version</a>
of Boost.MultiIndex for further information.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>const_mem_fun_explicit</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if const ChainedPtr&amp; is not convertible to const Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>const_mem_fun_explicit</code> provides the very same functionality as
its <code>const_mem_fun</code> analogous instantiation. For example, given the type
</p>
<blockquote><pre>
<span class=keyword>struct</span> <span class=identifier>A</span>
<span class=special>{</span>
<span class=keyword>int</span> <span class=identifier>f</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
the extractor <code>const_mem_fun&lt;A,int,&amp;A::f></code> can be replaced by
<code>const_mem_fun_explicit&lt;A,int,int (A::*)()const,&amp;A::f></code>.
</p>
<h3><a name="mem_fun_explicit">Class template <code>mem_fun_explicit</code></a></h3>
<p>
For analogy with <a href="#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,
a variation of <a href="#mem_fun"><code>mem_fun</code></a> is provided accepting
an additional parameter with the type of the pointer to non-constant member function
used for extraction.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span>
<span class=keyword>class</span> <span class=identifier>Class</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Type</span><span class=special>,</span>
<span class=keyword>typename</span> <span class=identifier>PtrToMemberFunctionType</span><span class=special>,</span><span class=identifier>PtrToMemberFunctionType</span> <span class=identifier>PtrToMemberFunction</span>
<span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>mem_fun_explicit</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>remove_reference</span><span class=special>&lt;</span><span class=identifier>Type</span><span class=special>&gt;::</span><span class=identifier>type</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=comment>// only provided if ChainedPtr&amp; is not convertible to Class&amp;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>ChainedPtr</span><span class=special>&gt;</span> <span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>ChainedPtr</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Class</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>Type</span> <span class=keyword>operator</span><span class=special>()(</span><span class=keyword>const</span> <span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<h3><a name="boost_multi_index_const_mem_fun">Macro
<code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code></a></h3>
<h3><a name="boost_multi_index_const_mem_fun">Macros
<code>BOOST_MULTI_INDEX_CONST_MEM_FUN</code>
and <code>BOOST_MULTI_INDEX_MEM_FUN</code></a></h3>
<blockquote><pre>
<span class=identifier>BOOST_MULTI_INDEX_CONST_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span>
</pre></blockquote>
<p>
Use this macro when writing cross-platform code selectively using
<code>const_mem_fun_explicit</code> in place of <code>const_mem_fun</code> for
compilers not supporting the latter. In the usual cases, the macro expands to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>const_mem_fun</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>const_mem_fun_explicit</span><span class=special>&lt;</span>
<span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(</span><span class=identifier>Class</span><span class=special>::*)()</span><span class=keyword>const</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
for MSVC++ 6.0 or lower.
</p>
<h3><a name="boost_multi_index_mem_fun">Macro
<code>BOOST_MULTI_INDEX_MEM_FUN</code></a></h3>
<blockquote><pre>
<span class=identifier>BOOST_MULTI_INDEX_MEM_FUN</span><span class=special>(</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>MemberFunName</span><span class=special>)</span>
</pre></blockquote>
<p>
By default, the macro expands to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>mem_fun</span><span class=special>&lt;</span><span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span><span class=special>&gt;</span>
</pre></blockquote>
<p>
but it resolves to
</p>
<blockquote><pre>
<span class=special>::</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>multi_index</span><span class=special>::</span><span class=identifier>mem_fun_explicit</span><span class=special>&lt;</span>
<span class=identifier>Class</span><span class=special>,</span><span class=identifier>Type</span><span class=special>,</span><span class=identifier>Type</span> <span class=special>(</span><span class=identifier>Class</span><span class=special>::*)()</span><span class=special>,&amp;</span><span class=identifier>Class</span><span class=special>::</span><span class=identifier>MemberFunName</span>
<span class=special>&gt;</span>
</pre></blockquote>
<p>
for MSVC++ 6.0 or lower.
Portability macros for usage of <code>const_mem_fun</code> and <code>mem_fun</code>.
Although no longer needed in modern compilers, some users might still decide to
resort to them as they provide a slightly more concise syntax.
</p>
<h2>
@ -959,7 +782,7 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_equal_to</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=comment>// comparison functors:</span>
@ -967,10 +790,10 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_compare</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=comment>// hash functors:</span>
@ -978,7 +801,7 @@ Type operator()(<br>
<span class=keyword>struct</span> <span class=identifier>composite_key_hash</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span><span class=special>;</span> <span class=comment><b>// deprecated</b></span>
<span class=special>}</span> <span class=comment>// namespace boost::multi_index</span>
@ -1176,10 +999,8 @@ instantiations as their extracted key.
which the <code>composite_key_result</code> type is associated. Objects of type
<code>composite_key_result</code> returned by a composite key must be always treated
as <i>temporary</i>, i.e. they should not be stored or copied.
<code>composite_key_result</code> is <i>not</i> guaranteed to be a model of
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> or
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
<code>composite_key_result</code> is <i>not</i> guaranteed to be
<code>DefaultConstructible</code> or <code>CopyAssignable</code>.
Every object of type <code>composite_key_result&lt;CompositeKey></code> is
internally associated to the <code>CompositeKey</code> from which it is returned
and the object of type <code>CompositeKey::value_type</code> to which the
@ -1351,19 +1172,14 @@ collection of elementary equality predicates.
<p>
<code>Pred0</code>, ... , <code>Predn</code> are the types of the equality
predicates stored by <code>composite_key_equal_to</code>. Each of these types
must be a <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a>. At least an
binary predicates stored by <code>composite_key_equal_to</code>. Each of these predicates
must be <code>CopyConstructible</code> and <code>CopyAssignable</code>. At least an
equality predicate must be provided. The maximum number of equality predicates of
a <code>composite_key_equal_to</code> instantiation is implementation defined.
<code>composite_key_equal_to</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
It is also
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>
if each <code>Predi</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also <code>DefaultConstructible</code>
if each <code>Predi</code> is <code>DefaultConstructible</code> in its turn.
</p>
<p>
@ -1451,66 +1267,18 @@ the result is determined to be <code>false</code>.
<code>composite_key_result_equal_to</code></a></h4>
<p>
<code>composite_key_result_equal_to</code> acts as a particularization of
<code>composite_key_equal_to</code> where all the comparison predicates supplied
are instantiations of <code>std::equal_to</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_equal_to</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_equal_to&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_equal_to&lt;Pred0,...,Predn>::operator()</code>, taking
<blockquote>
<code>Predi = std::equal_to&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Predi</code> imposed by
<code>composite_key_equal_to</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_equal_to</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
Deprecated. Use <code>std::equal_to&lt;CompositeKeyResult&gt;</code> instead.
</p>
<h4><a name="equal_to_composite_key_result">Specialization of
<code>std::equal_to</code> for <code>composite_key</code> results</a></h4>
<p>
<code>std::equal_to&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface
and functionality as <code>composite_key_result_equal_to&lt;CompositeKeyResult></code>.
<code>std::equal_to&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
an instantiation of <code>composite_key_result</code>,
behaves as a particularization of
<code>composite_key_equal_to</code> where all the comparison predicates supplied
are instantiations of <code>std::equal_to</code>.
</p>
<blockquote><pre>
@ -1544,6 +1312,27 @@ and functionality as <code>composite_key_result_equal_to&lt;CompositeKeyResult><
<span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::equal:to&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_equal_to&lt;Pred0,...,Predn>::operator()</code>, taking
<blockquote>
<code>Predi = std::equal_to&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Predi</code> imposed by
<code>composite_key_equal_to</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::equal_to&lt;CompositeKeyResult></code>
is <code>DefaultConstructible</code>, <code>CopyConstructible</code> and
<code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_comparison">Comparison</a></h3>
<h4><a name="composite_key_compare">Class template
@ -1598,19 +1387,15 @@ collection of elementary comparison predicates.
<p>
<code>Compare0</code>, ... , <code>Comparen</code> are the types of the comparison
predicates stored by <code>composite_key_compare</code>. Each of these types
must be a <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a>. At least a
binary predicates stored by <code>composite_key_compare</code>. Each of these predicates must be
<code>CopyConstructible</code> and <code>CopyAssignable</code>. At least a
comparison predicate must be provided. The maximum number of comparison predicates of
a <code>composite_key_compare</code> instantiation is implementation defined.
<code>composite_key_compare</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>
if each <code>Comparei</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
<code>DefaultConstructible</code>
if each <code>Comparei</code> is <code>DefaultConstructible</code> in its turn.
</p>
<p>
@ -1728,139 +1513,24 @@ bool operator()(<br>
<code>composite_key_result_less</code></a></h4>
<p>
<code>composite_key_result_less</code> acts as a particularization of
<code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::less</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_less</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_less&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::less&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_less</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
Deprecated. Use <code>std::less&lt;CompositeKeyResult&gt;</code> instead.
</p>
<h4><a name="composite_key_result_greater">Class template
<code>composite_key_result_greater</code></a></h4>
<p>
<code>composite_key_result</code> acts as a particularization of
<code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::greater</code>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_greater</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>first_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>first_argument_type</span> <span class=identifier>second_argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=keyword>bool</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey1</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey2</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey1</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey2</span><span class=special>&gt;</span> <span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=keyword>operator</span><span class=special>()(</span>
<span class=keyword>const</span> <span class=identifier>Value</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;&amp;</span> <span class=identifier>y</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_greater&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::greater&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_greater</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
Deprecated. Use <code>std::greater&lt;CompositeKeyResult&gt;</code> instead.
</p>
<h4><a name="less_composite_key_result">Specialization of <code>std::less</code> for
<code>composite_key</code> results</a></h4>
<p>
<code>std::less&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface
and functionality as <code>composite_key_result_less&lt;CompositeKeyResult></code>.
<code>std::less&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
an instantiation of <code>composite_key_result</code>, behaves as a particularization of
<code>composite_key_compare</code> where all the comparison predicates supplied are
instantiations of <code>std::less</code>.
</p>
<blockquote><pre>
@ -1904,15 +1574,38 @@ and functionality as <code>composite_key_result_less&lt;CompositeKeyResult></cod
<span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::less&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::less&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::less&lt;CompositeKeyResult></code>
is <code>CopyConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h4><a name="greater_composite_key_result">Specialization of <code>std::greater</code> for
<code>composite_key</code> results</a></h4>
<p>
<code>std::greater&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface
and functionality as <code>composite_key_result_greater&lt;CompositeKeyResult></code>.
<code>std::greater&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
an instantiation of <code>composite_key_result</code>, behaves as a particularization of
<code>composite_key_compare</code> where all the comparison predicates supplied
are instantiations of <code>std::greater</code>.
</p>
<blockquote><pre>
<span class=keyword>namespace</span> <span class=identifier>std</span><span class=special>{</span>
@ -1954,6 +1647,27 @@ and functionality as <code>composite_key_result_greater&lt;CompositeKeyResult></
<span class=special>}</span> <span class=comment>// namespace std</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>std::greater&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_compare&lt;Compare0,...,Comparen>::operator()</code>, taking
<blockquote>
<code>Comparei = std::greater&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Comparei</code> imposed by
<code>composite_key_compare</code>, each of these types must be
<code>DefaultConstructible</code>. <code>std::greater&lt;CompositeKeyResult></code>
is <code>CopyConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_hashing">Hashing</a></h3>
<h4><a name="composite_key_hash">Class template
@ -1991,23 +1705,17 @@ instantiations based on a collection of elementary hash functors.
</pre></blockquote>
<p>
<code>Hash0</code>, ... , <code>Hashn</code> are the types of the hash functors
stored by <code>composite_key_hash</code>. Each of these types
must be a
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary Function</code></a>
returning a value of type <code>std::size_t</code> in the range
<code>[0, std::numeric_limits&lt;std::size_t&gt;::max())</code>.
At least a
hash functor must be provided. The maximum number of hash functors of
<code>Hash0</code>, ... , <code>Hashn</code> are the types of the hash unary function objects
stored by <code>composite_key_hash</code>. Each of these objects
must be <code>CopyConstructible</code> and <code>CopyAssignable</code>
and return a value of type <code>std::size_t</code> in the range
[0, <code>std::numeric_limits&lt;std::size_t&gt;::max())</code>).
At least a hash functor must be provided. The maximum number of hash functors of
a <code>composite_key_hash</code> instantiation is implementation defined.
<code>composite_key_hash</code> is
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
It is also
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>
if each <code>Hashi</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>.
<code>CopyConstructible</code> and <code>CopyAssignable</code>.
It is also <code>DefaultConstructible</code>
if each <code>Hashi</code> is <code>DefaultConstructible</code> in its turn.
</p>
<h4>Notation</h4>
@ -2081,50 +1789,7 @@ with <code>N=length(x)-1</code>.
<code>composite_key_result_hash</code></a></h4>
<p>
<code>composite_key_result_hash</code> acts as a particularization of
<code>composite_key_hash</code> where all the hash functors supplied
are instantiations of
<a href="../../../functional/hash/index.html"><code>boost::hash</code></a>.
</p>
<blockquote><pre>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKeyResult</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>composite_key_result_hash</span>
<span class=special>{</span>
<span class=keyword>typedef</span> <span class=identifier>CompositeKeyResult</span> <span class=identifier>argument_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>std</span><span class=special>::</span><span class=identifier>size_t</span> <span class=identifier>result_type</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>CompositeKey</span><span class=special>&gt;</span>
<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=identifier>composite_key_result</span><span class=special>&lt;</span><span class=identifier>CompositeKey</span><span class=special>&gt;</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Value0</span><span class=special>,...,</span><span class=keyword>typename</span> <span class=identifier>Valuen</span><span class=special>&gt;</span>
<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=identifier>tuple</span><span class=special>&lt;</span><span class=identifier>Value0</span><span class=special>,...,</span><span class=identifier>Valuen</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>)</span><span class=keyword>const</span><span class=special>;</span>
<span class=special>};</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>composite_key_result_hash&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_hash&lt;Hash0,...,Hashn>::operator()</code>, taking
<blockquote>
<code>Hashi = boost::hash&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Hashi</code> imposed by
<code>composite_key_hash</code>, each of these types must be
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a>. <code>composite_key_result_hash</code>
is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
<code>Default Constructible</code></a> and
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
Deprecated. Use <code>boost::hash&lt;CompositeKeyResult&gt;</code> instead.
</p>
<h4><a name="hash_composite_key_result">Specialization of
@ -2132,9 +1797,11 @@ is <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
for <code>composite_key</code> results</a></h4>
<p>
<code>boost::hash&lt;CompositeKeyResult></code>, for <code>CompositeKeyResult</code>
being an instantiation of <code>composite_key_result</code>, has the same interface
and functionality as <code>composite_key_result_hash&lt;CompositeKeyResult></code>.
<code>boost::hash&lt;CompositeKeyResult></code>, with <code>CompositeKeyResult</code>
an instantiation of <code>composite_key_result</code>, behaves as a particularization of
<code>composite_key_hash</code> where all the hash functors supplied
are instantiations of
<a href="../../../functional/hash/index.html"><code>boost::hash</code></a>.
</p>
<blockquote><pre>
@ -2158,6 +1825,27 @@ and functionality as <code>composite_key_result_hash&lt;CompositeKeyResult></cod
<span class=special>}</span> <span class=comment>// namespace boost</span>
</pre></blockquote>
<p>
<code>CompositeKeyResult</code> must be an instantiation of
<code>composite_key_result</code> for some type
<code>composite_key&lt;KeyFromValue0,...,KeyFromValuen></code>.
<code>boost::hash&lt;CompositeKeyResult>::operator()</code> is
then equivalent to
<code>composite_key_hash&lt;Hash0,...,Hashn>::operator()</code>, taking
<blockquote>
<code>Hashi = boost::hash&lt;KeyFromValuei::result_type></code> for all
<code>i = 0,...,n</code>.
</blockquote>
</p>
<p>
In addition to the requirements on <code>Hashi</code> imposed by
<code>composite_key_hash</code>, each of these types must be
<code>DefaultConstructible</code>. <code>boost::hash&lt;CompositeKeyResult></code> is
<code>DefaultConstructible</code>, <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</p>
<h3><a name="ckey_result_semantics">Semantics of
<code>composite_key_result</code></a></h3>
@ -2204,13 +1892,10 @@ of (<code>Hashi</code>, <code>Predi</code>).</p>
<p>
As for comparison, consider an instantiation of <code>composite_key_compare</code>
with types <code>Compare0</code>, ... , <code>Comparen</code> such that each
<code>Comparei</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><code>Strict
Weak Ordering</code></a> on the type <code>Ti</code>. Then, for a
<code>Comparei</code> induces a strict weak ordering
on the type <code>Ti</code>. Then, for a
<code>CompositeKey</code> type defined in the same manner as above,
<code>composite_key_compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html"><code>Strict
Weak Ordering</code></a> on elements of type
<code>composite_key_compare</code> induces a strict weak ordering on elements of type
<code>composite_key_result&lt;CompositeKey></code>, and the order induced
is lexicographical. Also, the following types are
<a href="ord_indices.html#set_operations"><code>Compatible Keys</code></a> of
@ -2263,9 +1948,9 @@ Compiler specifics
<br>
<p>Revised June 25th 2008</p>
<p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -88,6 +88,8 @@ synopsis</a>
</h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -269,7 +271,6 @@ operators and functions associated with the index (vg. comparison and
<span class=keyword>struct</span> <span class=identifier>nth_index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Tag</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>index</span> <span class=special>{</span><span class=keyword>typedef</span> <b>implementation defined</b> <span class=identifier>type</span><span class=special>;};</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>int</span> <span class=identifier>N</span><span class=special>&gt;</span>
<span class=keyword>struct</span> <span class=identifier>nth_index_iterator</span> <span class=comment><b>// deprecated</b></span>
@ -295,13 +296,23 @@ operators and functions associated with the index (vg. comparison and
<span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),
</span><span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>,</span>
<span class=keyword>const</span> <span class=identifier>ctor_args_list</span><span class=special>&amp;</span> <span class=identifier>args_list</span><span class=special>=</span><span class=identifier>ctor_args_list</span><span class=special>(),</span>
<span class=keyword>const</span> <span class=identifier>allocator_type</span><span class=special>&amp;</span> <span class=identifier>al</span><span class=special>=</span><span class=identifier>allocator_type</span><span class=special>());</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=special>~</span><span class=identifier>multi_index_container</span><span class=special>();</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=keyword>const</span> <span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>multi_index_container</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>,</span><span class=identifier>IndexSpecifierList</span><span class=special>,</span><span class=identifier>Allocator</span><span class=special>&gt;&amp;</span> <span class=keyword>operator</span><span class=special>=(</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>Value</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>)</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -507,9 +518,8 @@ scheme outlined in the
<p>
<code>multi_index_container</code> is instantiated with the following types:
<ol>
<li><code>Value</code> is the
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>
type of the elements contained.
<li><code>Value</code> is the type of the elements contained. <code>Value</code> must be
<code>Erasable</code> from <code>multi_index_container</code>.
</li>
<li><code>IndexSpecifierList</code> specifies the indices that the
<code>multi_index_container</code> is composed of. It must be a non-empty
@ -522,17 +532,15 @@ scheme outlined in the
MPL sequence can be used.
</li>
<li><code>Allocator</code> must be an allocator of <code>Value</code> objects
satisfying the associated C++ requirements at <b>[lib.allocator.requirements]</b>.
satisfying the associated C++ requirements at <b>[allocator.requirements]</b>.
The following relaxations to the standard requirements are allowed:
<ul>
<li>Non-equal allocator instances are supported: swapping two non-equal
instances must not throw any exception.
</li>
</li>s
<li>For every type <code>T</code>,
the type <code>Allocator::rebind&lt;T&gt;::other::pointer</code> can be any
kind of
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"><code>Random
Access Iterator</code></a>, provided that it is explicitly constructible from
kind of random access iterator, provided that it is explicitly constructible from
the literal <code>0</code> (standing here as the null pointer) or from any
<code>p</code> of type <code>T*</code> pointing into an area allocated by
some instance of <code>Allocator</code> or some other allocator type rebound
@ -564,9 +572,8 @@ implicit conversion from
to <code>const ctor_args_list&amp;</code>. This type is used for
providing the construction arguments of the indices of the
<code>multi_index_container</code>. <code>ctor_args_list</code> is
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html"><code>Default
Constructible</code></a>, provided that all <code>ctor_args</code> types
involved are default constructible.
<code>DefaultConstructible</code>, provided that all <code>ctor_args</code> types
involved are <code>DefaultConstructible</code>.
</blockquote>
<code>index_specifier_type_list</code>
@ -685,14 +692,14 @@ specified allocator and the default value of <code>ctor_args_list</code>.<br>
<code>template&lt;typename InputIterator><br>
multi_index_container(<br>
&nbsp;&nbsp;InputIterator first,InputIterator last,<br>
&nbsp;&nbsp;const ctor_args_list&amp; comp=ctor_args_list(),<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>Value</code> or a type convertible to <code>Value</code>.
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
<code>Value</code> is
<code>EmplaceConstructible</code> into <code>multi_index_container</code>
from <code>*first</code>.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b> Constructs and empty <code>multi_index_container</code> using the
specified argument list and allocator and fills it with
@ -703,18 +710,43 @@ on the acceptance by all the indices of the <code>multi_index_container</code>.<
the number of elements in [<code>first</code>,<code>last</code>).<br>
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list,<br>
&nbsp;&nbsp;const ctor_args_list&amp; args_list=ctor_args_list(),<br>
&nbsp;&nbsp;const allocator_type&amp; al=allocator_type());</code>
<blockquote>
<b>Effects:</b> Equivalent to
<code>multi_index_container(list.begin(),list.end(),args_list,al)</code>.
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Constructs a copy of <code>x</code>, copying its
elements as well as its internal objects (key extractors, comparison objects,
allocator.)<br>
elements as well as its internal objects (those specified
in <code>ctor_args_list</code> and the allocator.)<br>
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> <code>O(x.size()*log(x.size()) + C(x.size()))</code>.
</blockquote>
<code>multi_index_container(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Constructs a <code>multi_index_container</code> by moving the
elements of <code>x</code> and copying its internal objects (those specified
in <code>ctor_args_list</code> and the allocator.)<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Complexity:</b> Constant.
</blockquote>
<code>~multi_index_container()</code>
<blockquote>
<b>Effects:</b> Destroys the <code>multi_index_container</code> and all the elements
@ -726,7 +758,9 @@ contained. The order in which the elements are destroyed is not specified.<br>
&nbsp;&nbsp;const multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; x);</code>
<blockquote>
Replaces the elements and internal objects of the <code>multi_index_container</code>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements and internal objects of the <code>multi_index_container</code>
with copies from <code>x</code>.<br>
<b>Postconditions:</b> <code>*this==x</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
@ -737,6 +771,39 @@ C(x.size()))</code>.<br>
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Replaces the elements of <code>multi_index_container</code>
with those of <code>x</code> and its internal objects with copies from the
corresponding objects in <code>x</code>.<br>
<b>Postconditions:</b> If <code>x==y</code> just
before the movement, <code>*this==y</code>. The order on every index
of the <code>multi_index_container</code> is preserved as well.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n)</code>.<br>
<b>Exception safety:</b> Strong, provided the copy and assignment operations
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>multi_index_container&lt;Value,IndexSpecifierList,Allocator>&amp; operator=(<br>
&nbsp;&nbsp;std::initializer_list&lt;Value&gt; list);</code>
<blockquote>
<b>Requires:</b> <code>Value</code> is <code>CopyInsertable</code> into
<code>multi_index_container</code>.<br>
<b>Effects:</b> Replaces the elements the <code>multi_index_container</code>
with copies of the elements of <code>list</code>, inserted in the specified order.
Insertion of each element may or may not succeed depending
on the acceptance by all the indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> <code>*this</code>.<br>
<b>Complexity:</b> <code>O(n + I(m))</code>, where <code>m</code> is the
number of elements of <code>list</code>.<br>
<b>Exception safety:</b> Strong, provided the copy and assignment operations
of the types of <code>ctor_args_list</code> do not throw.
</blockquote>
<code>allocator_type get_allocator()const;</code>
<blockquote>
@ -883,8 +950,7 @@ these, the following concepts are used. A type <code>T</code> is <i>serializable
archive (XML archive) and later retrieved from an input archive (XML archive) associated to
the same storage. If <code>x'</code> of type <code>T</code> is loaded from the
serialization information saved from another object <code>x</code>, we say that
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html"><code>Binary Predicate</code></a>
<code>x'</code> is a <i>restored copy</i> of <code>x</code>. Given a binary predicate
<code>Pred</code> over (<code>T</code>, <code>T</code>), and objects <code>p</code>
and <code>q</code> of type <code>Pred</code>, we say that <code>q</code>
is <i>serialization-compatible</i> with <code>p</code> if
@ -930,9 +996,9 @@ Index reference
<br>
<p>Revised November 6th 2008</p>
<p>Revised July 3rd 2013</p>
<p>&copy; Copyright 2003-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -97,6 +97,8 @@ their associated <a href="#ord_indices">ordered index</a> classes.
<code>"boost/multi_index/ordered_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -190,15 +192,13 @@ together, with minor differences explicitly stated when they exist.
</p>
<p>
Except where noted, ordered indices (both unique and non-unique) are models of
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
<code>Sorted Associative Container</code></a> and
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
<code>Unique Associative Container</code></a>, much as <code>std::set</code>s
are. Accordingly, validity of iterators and references to elements is
preserved. We only provide descriptions of those types and operations that are
either not present in the concepts modeled or do not exactly conform to the
requirements for these types of containers.
Except where noted or if the corresponding interface does not exist,
ordered indices (both unique and non-unique) satisfy the C++ requirements
for associative containers at <b>[associative.reqmts]</b>
(supporting unique and equivalent keys, respectively.)
Accordingly, validity of iterators and references to elements is
preserved. We only provide descriptions of those types and operations that
do not exactly conform to or are not mandated by the standard requirements.
</p>
<blockquote><pre>
@ -241,6 +241,7 @@ requirements for these types of containers.
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -270,16 +271,24 @@ requirements for these types of containers.
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>iterator</span> <span class=identifier>emplace_hint</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>size_type</span> <span class=identifier>erase</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>key_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</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=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
@ -436,9 +445,8 @@ following types:
which determines the mechanism for extracting a key from <code>Value</code>,
must be a model of <a href="key_extraction.html#key_extractors">
<code>Key Extractor</code></a> from <code>Value</code>. <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> on elements of
<code>KeyFromValue::result_type</code>.
<code>CopyConstructible</code> binary predicate inducing a strict weak order
on elements of <code>KeyFromValue::result_type</code>.
</p>
<h4><a name="constructors">Constructors, copy and assignment</a></h4>
@ -461,6 +469,18 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<h4><a name="iterators">Iterators</a></h4>
<code>iterator&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator_to(const value_type&amp; x);<br>
@ -475,9 +495,65 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the 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>
<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 took place. On successful insertion,
<code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
iterator emplace_hint(iterator position, Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> into the <code>multi_index_container</code> to which
the 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>
<code>position</code> is used as a hint to improve the efficiency of the
operation. If succesful, insertion happens as close as possible to the
location just prior to <code>position</code>.<br>
<b>Returns:</b> On successful insertion, an iterator to the newly inserted
element. Otherwise, an iterator 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> <code>O(H(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@ -495,10 +571,16 @@ one element can be causing insertion not to be allowed.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>iterator insert(iterator position,const value_type&amp; x);</code>
<code>iterator insert(iterator position,const value_type&amp; x);</code><br>
<code>iterator insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> into the <code>multi_index_container</code> to which
the index belongs if
<ul>
@ -522,24 +604,37 @@ allowed.<br>
void insert(InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<b>Requires:</b> <code>InputIterator</code> is an input iterator.
<code>value_type</code> is <code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>iterator</span> <span class=identifier>hint</span><span class=special>=</span><span class=identifier>end</span><span class=special>();</span>
<span class=keyword>while</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=identifier>hint</span><span class=special>=</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>hint</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
</pre></blockquote>
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it into the <code>multi_index_container</code>
to which this 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>
<b>Complexity:</b> <code>O(m*H(n+m))</code>, where
<code>m</code> is the number of elements in [<code>first</code>,
<code>last</code>).<br>
<b>Exception safety:</b> Basic.<br>
</blockquote>
<code>void insert(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>())</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
@ -575,11 +670,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if, for the value <code>x</code>
@ -604,9 +702,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -634,9 +731,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
@ -673,9 +769,8 @@ is rethrown.
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
from <code>value_type</code>. <code>mod</code> is a
unary function object accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod')</code>,
@ -690,14 +785,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>key_from_value</code> is a read/write
<a href="key_extraction.html#key_extractors"><code>Key Extractor</code></a>
from <code>value_type</code>. <code>Modifier</code> and <code>Rollback</code>
are models of <a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
from <code>value_type</code>. <code>mod</code> and <code>back</code>
are unary function objects accepting arguments of type
<code>key_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.
The sequence of operations <code>mod(k)</code>,
<code>back(k)</code>, where <code>k</code> is the key of the element
pointed to by <code>position</code>, restores k to its original state.<br>
pointed to by <code>position</code>, restores <code>k</code> to its original state.<br>
<b>Effects:</b> Equivalent to <code>modify(position,mod',back')</code>,
with <code>mod'</code> and <code>back</code> defined in such a way that
<code>mod'(x)</code> is the same as <code>mod(key(x))</code> and
@ -724,10 +818,7 @@ the index.<br>
<p>
Ordered indices provide the full lookup functionality required by
<a href="http://www.sgi.com/tech/stl/SortedAssociativeContainer.html">
<code>Sorted Associative Containers</code></a> and
<a href="http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html">
<code>Unique Associative Containers</code></a>, namely <code>find</code>,
<b>[associative.reqmts]</b>, namely <code>find</code>,
<code>count</code>, <code>lower_bound</code>, <code>upper_bound</code>
and <code>equal_range</code>. Additionally, these member functions are
templatized to allow for non-standard arguments, so extending
@ -737,20 +828,14 @@ concept.
</p>
<p>
Consider a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
Consider a binary predicate <code>Compare</code> inducing a strict
weak order over values of type <code>Key</code>. A pair of types (<code>CompatibleKey</code>,
<code>CompatibleCompare</code>) is said to be a <i>compatible extension</i>
of <code>Compare</code> if
<ol>
<li><code>CompatibleCompare</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>Key</code>,
<li><code>CompatibleCompare</code> is a binary predicate over (<code>Key</code>,
<code>CompatibleKey</code>),</li>
<li><code>CompatibleCompare</code> is a
<a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">
<code>Binary Predicate</code></a> over (<code>CompatibleKey</code>,
<li><code>CompatibleCompare</code> is a binary predicate over (<code>CompatibleKey</code>,
<code>Key</code>),</li>
<li>if <code>c_comp(ck,k1)</code> then <code>!c_comp(k1,ck)</code>,</li>
<li>if <code>!c_comp(ck,k1)</code> and <code>!comp(k1,k2)</code> then
@ -913,15 +998,11 @@ are modeled after the following concepts.
</p>
<p>
Consider a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> <code>Compare</code> over values
of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
Consider a binary predicate <code>Compare</code> inducing a strict
weak order over values of type <code>Key</code>. A type <code>LowerBounder</code> is said to be
a <i>lower bounder</i> of <code>Compare</code> if
<ol>
<li><code>LowerBounder</code> is a
<a href="http://www.sgi.com/tech/stl/Predicate.html">
<code>Predicate</code></a> over <code>Key</code>,</li>
<li><code>LowerBounder</code> is a predicate over <code>Key</code>,</li>
<li>if <code>lower(k1)</code> and <code>!comp(k2,k1)</code> then
<code>lower(k2)</code>,</li>
</ol>
@ -930,9 +1011,7 @@ for every <code>lower</code> of type <code>LowerBounder</code>,
<code>k2</code> of type <code>Key</code>. Similarly, an <i>upper bounder</i>
is a type <code>UpperBounder</code> such that
<ol>
<li><code>UpperBounder</code> is a
<a href="http://www.sgi.com/tech/stl/Predicate.html">
<code>Predicate</code></a> over <code>Key</code>,</li>
<li><code>UpperBounder</code> is a predcate over <code>Key</code>,</li>
<li>if <code>upper(k1)</code> and <code>!comp(k1,k2)</code> then
<code>upper(k2)</code>,</li>
</ol>
@ -1024,9 +1103,9 @@ Hashed indices
<br>
<p>Revised December 21st 2009</p>
<p>Revised July 6th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -92,6 +92,8 @@ its associated <a href="#rnd_indices">random access index</a> class.
<code>"boost/multi_index/random_access_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -161,33 +163,31 @@ is preserved in all operations, regardless of the capacity status.
</p>
<p>
As is the case with sequenced indices, random access indices have the
following limitations with respect to STL sequence containers:
Except where noted or if the corresponding interface does not exist, random access
indices verify the same container requirements as <code>std::vector</code>
plus the requirements for <code>std::list</code> specific list operations at
<b>[list.ops]</b>. Some of the most important differences with respect to
<code>std::vector</code> are:
<ul>
<li>Random access indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html">
<code>Assignable</code></a> (like any other index.)</li>
<li>Insertions into a random access index may fail due to clashings
with other indices. This alters the semantics of the operations
provided with respect to their analogues in STL sequence containers.
<li>Random access indices do not provide memory contiguity, and hence do not
have <code>data</code> member functions.
</li>
<li>Elements in a random access index are not mutable, and can only be changed
<li>The complexity of some operations, notably insertion and deletion, differ
from those of <code>std::vector</code>.
</li>
<li>Unlike as in <code>std::vector</code>, insertions into a random access index
may fail due to clashings with other indices. This alters the semantics
of the operations provided with respect to their analogues in
<code>std::vector</code>.
</li>
<li>Elements in a randon access index are not mutable, and can only be changed
by means of <a href="#replace"><code>replace</code></a> and
<a href="#modify"><code>modify</code></a> member functions.
</li>
</ul>
Having these restrictions into account, random access indices are models
of <a href="http://www.sgi.com/tech/stl/RandomAccessContainer.html">
<code>Random Access Container</code></a> and
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
<code>Back Insertion Sequence</code></a>. Although these indices do
not model
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
<code>Front Insertion Sequence</code></a>, because front insertion
and deletion take linear time, front operations are nonetheless provided
to match the interface of sequenced indices.
We only describe those types and operations that are
either not present in the concepts modeled or do not exactly conform
to the requirements for these types of containers.
<li><code>push_front</code> and <code>pop_front</code> are provided for
compatibility with sequenced indices, even though they take linear time to execute.
</li></ul>
</p>
<blockquote><pre>
@ -203,7 +203,7 @@ to the requirements for these types of containers.
<span class=keyword>public</span><span class=special>:</span>
<span class=comment>// types:</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
@ -223,9 +223,11 @@ to the requirements for these types of containers.
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>)</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -255,8 +257,10 @@ to the requirements for these types of containers.
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>capacity</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>reserve</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>m</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>shrink_to_fit</span><span class=special>();</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// access:</span>
@ -267,20 +271,32 @@ to the requirements for these types of containers.
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_front</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_front</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_back</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_back</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>size_type</span> <span class=identifier>m</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</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=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
@ -445,17 +461,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code>template &lt;class InputIterator><br>
void assign(InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>clear</span><span class=special>();</span>
@ -463,6 +484,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<code>void assign(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>void assign(size_type n,const value_type&amp; value);</code>
<blockquote>
@ -500,6 +530,7 @@ is preserved in all insertions, regardless of the capacity status.
</blockquote>
<a name="reserve"><code>void reserve(size_type m);</code></a>
<blockquote>
<b>Effects:</b> If the previous value of <code>capacity()</code>
was greater than or equal to <code>m</code>, nothing is done;
@ -511,52 +542,123 @@ otherwise <code>O(n)</code>.<br>
otherwise, strong.<br>
</blockquote>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code>
<code>void shrink_to_fit();</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&gt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span>
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&lt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>erase</span><span class=special>(</span><span class=identifier>begin</span><span class=special>()+</span><span class=identifier>n</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
<b>Effects:</b> Reduces <code>capacity()</code> to <code>size()</code>.<br>
<b>Complexity:</b> If the capacity is not changed, constant;
otherwise <code>O(n)</code>.<br>
<b>Exception safety:</b> If the capacity is not changed, <code>nothrow</code>;
otherwise, strong.<br>
</blockquote>
<code>void resize(size_type n);<br>
void resize(size_type n,const value_type&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> If <code>size()&lt;n</code>, tries to append <code>n-size()</code> default-inserted
elements (first version) or copies of <code>x</code> (second version) at the end of
the index. If <code>n&lt;size()</code>, erases the last <code>size()-n</code> elements.<br>
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
to be <code>n</code> after this operation (other indices may ban insertions.)
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_front(Args&amp;&amp;... args);</code>
<blockquote>
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if
no other index of the <code>multi_index_container</code> bans the insertion.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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> <code>O(n+I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_front(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if
no other index of the <code>multi_index_container</code> bans the insertion.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</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=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</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>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_back(Args&amp;&amp;... args);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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>
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_back(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</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>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(iterator position,Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<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 took place. On successful insertion,
<code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
@ -564,7 +666,7 @@ is <code>true</code> if and only if insertion took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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> <code>O(shl(end()-position,1) + I(n))</code>.<br>
<b>Complexity:</b> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote>
@ -584,23 +686,32 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
<code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>InputIterator</code> is an input iterator.
<code>value_type</code> is
<code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>while</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=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
</pre></blockquote>
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it before <code>position</code> if insertion is allowed by all
other indices of the <code>multi_index_container</code>.<br>
<b>Complexity:</b> <code>O(shl(end()-position,m) + m*I(n+m))</code>,
where <code>m</code> is the number of elements in
[<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> Basic.
</blockquote>
<code>void insert(iterator position,std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
@ -626,11 +737,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if replacing is allowed by all other indices of the
@ -649,17 +763,16 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and rearranges <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on
random access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not succeed. If the
rearrangement fails, the element is erased.<br>
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not succeed. If the rearrangement
fails, the element is erased.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved if the
operation succeeds.<br>
<b>Returns:</b> <code>true</code> if the operation succeeded, <code>false</code>
@ -674,9 +787,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
@ -684,10 +796,10 @@ pointed to by <code>position</code>, restores all keys of the element
to their original state.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
pointed to by <code>position</code> and tries to rearrange <code>*position</code> into
all the indices of the <code>multi_index_container</code>. Rearrangement on
random access indices does not change the position of the element with respect
to the index; rearrangement on other indices may or might not succeed. If the
rearrangement fails, <code>back(e)</code> is invoked and the
all the indices of the <code>multi_index_container</code>. Rearrangement on sequenced
indices does not change the position of the element with respect to the index;
rearrangement on other indices may or might not succeed. If the rearrangement
fails, <code>back(e)</code> is invoked and the
element is kept at its original position in all indices.<br>
<b>Postconditions:</b> Validity of <code>position</code> is preserved except if
the element is erased under the conditions described below.<br>
@ -808,11 +920,10 @@ is the number of elements erased.<br>
<code>void merge(index class name&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
<b>Requires:</b> <code>std::less&lt;value_type&gt;</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&lt;value_type></code>.<br>
<code>std::less&lt;value_type&gt;</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
@ -832,9 +943,8 @@ otherwise, basic.<br>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
<b>Requires:</b> <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>).
@ -855,9 +965,8 @@ otherwise, basic.<br>
<code>void sort();</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
strict weark ordering over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to
<code>std::less&lt;value_type></code>. The sorting is stable, i.e.
equivalent elements preserve their relative position.<br>
@ -869,9 +978,8 @@ equivalent elements preserve their relative position.<br>
<code>template &lt;typename Compare> void sort(Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Requires:</b> <code>Compare</code> induces a
strict weak ordering over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
is stable, i.e. equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
@ -1000,9 +1108,9 @@ Key extraction
<br>
<p>Revised July 21st 2009</p>
<p>Revised July 14th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -92,6 +92,8 @@ its associated <a href="#seq_indices">sequenced index</a> class.
<code>"boost/multi_index/sequenced_index.hpp"</code></a> synopsis</a></h2>
<blockquote><pre>
<span class=preprocessor>#include</span> <span class=special>&lt;</span><span class=identifier>initializer_list</span><span class=special>&gt;</span>
<span class=keyword>namespace</span> <span class=identifier>boost</span><span class=special>{</span>
<span class=keyword>namespace</span> <span class=identifier>multi_index</span><span class=special>{</span>
@ -155,10 +157,15 @@ of iterators and references to elements is preserved in all operations.
</p>
<p>
There are a number of differences with respect to <code>std::lists</code>:
Except where noted or if the corresponding interface does not exist, sequenced
indices verify the same container requirements as <code>std::list</code>:
we only provide descriptions of those types and operations that are either not
present in <code>std::list</code> or behave differently. Some of the
most important differences are:
<ul>
<li>Sequenced indices are not <a href="http://www.sgi.com/tech/stl/Assignable.html">
<code>Assignable</code></a> (like any other index.)</li>
<li>The complexity of some operations, notably insertion and deletion, differ
from those of <code>std::list</code>.
</li>
<li>Unlike as in <code>std::list</code>, insertions into a sequenced index
may fail due to clashings with other indices. This alters the semantics
of the operations provided with respect to their analogues in
@ -169,16 +176,6 @@ There are a number of differences with respect to <code>std::lists</code>:
<a href="#modify"><code>modify</code></a> member functions.
</li>
</ul>
Having these restrictions into account, sequenced indices are models
of <a href="http://www.sgi.com/tech/stl/ReversibleContainer.html">
<code>Reversible Container</code></a>,
<a href="http://www.sgi.com/tech/stl/FrontInsertionSequence.html">
<code>Front Insertion Sequence</code></a> and
<a href="http://www.sgi.com/tech/stl/BackInsertionSequence.html">
<code>Back Insertion Sequence</code></a>. We only provide descriptions
of those types and operations that are either not present in the
concepts modeled or do not exactly conform to the requirements for these
types of containers.
</p>
<blockquote><pre>
@ -194,7 +191,7 @@ types of containers.
<span class=keyword>public</span><span class=special>:</span>
<span class=comment>// types:</span>
<span class=keyword>typedef</span> <span class=keyword>typename</span> <span class=identifier>node_type</span><span class=special>::</span><span class=identifier>value_type</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Value</span> <span class=identifier>value_type</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>tuples</span><span class=special>::</span><span class=identifier>null_type</span> <span class=identifier>ctor_args</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>TagList</span> <span class=identifier>tag_list</span><span class=special>;</span>
<span class=keyword>typedef</span> <span class=identifier>Allocator</span> <span class=identifier>allocator_type</span><span class=special>;</span>
@ -214,9 +211,11 @@ types of containers.
<span class=comment>// construct/copy/destroy:</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=keyword>const</span> <b>index class name</b><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<b>index class name</b><span class=special>&amp;</span> <span class=keyword>operator</span><span class=special>=(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=keyword>template</span> <span class=special>&lt;</span><span class=keyword>class</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>assign</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>value</span><span class=special>);</span>
<span class=identifier>allocator_type</span> <span class=identifier>get_allocator</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
@ -245,7 +244,8 @@ types of containers.
<span class=identifier>size_type</span> <span class=identifier>size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=identifier>size_type</span> <span class=identifier>max_size</span><span class=special>()</span><span class=keyword>const</span><span class=special>;</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>=</span><span class=identifier>value_type</span><span class=special>());</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>resize</span><span class=special>(</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=comment>// access:</span>
@ -254,20 +254,32 @@ types of containers.
<span class=comment>// modifiers:</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_front</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_front</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_front</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace_back</span><span class=special>(</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>push_back</span><span class=special>(</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>pop_back</span><span class=special>();</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span><span class=special>...</span> <span class=identifier>Args</span><span class=special>&gt;</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>emplace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Args</span><span class=special>&amp;&amp;...</span> <span class=identifier>args</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>pair</span><span class=special>&lt;</span><span class=identifier>iterator</span><span class=special>,</span><span class=keyword>bool</span><span class=special>&gt;</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>size_type</span> <span class=identifier>n</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>InputIterator</span><span class=special>&gt;</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>first</span><span class=special>,</span><span class=identifier>InputIterator</span> <span class=identifier>last</span><span class=special>);</span>
<span class=keyword>void</span> <span class=identifier>insert</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>initializer_list</span><span class=special>&lt;</span><span class=identifier>value_type</span><span class=special>&gt;</span> <span class=identifier>list</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>);</span>
<span class=identifier>iterator</span> <span class=identifier>erase</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=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=keyword>const</span> <span class=identifier>value_type</span><span class=special>&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>bool</span> <span class=identifier>replace</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>value_type</span><span class=special>&amp;&amp;</span> <span class=identifier>x</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>&gt;</span> <span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>);</span>
<span class=keyword>template</span><span class=special>&lt;</span><span class=keyword>typename</span> <span class=identifier>Modifier</span><span class=special>,</span><span class=keyword>typename</span> <span class=identifier>Rollback</span><span class=special>&gt;</span>
<span class=keyword>bool</span> <span class=identifier>modify</span><span class=special>(</span><span class=identifier>iterator</span> <span class=identifier>position</span><span class=special>,</span><span class=identifier>Modifier</span> <span class=identifier>mod</span><span class=special>,</span><span class=identifier>Rollback</span> <span class=identifier>back</span><span class=special>);</span>
@ -419,17 +431,22 @@ objects to which <code>*this</code> and <code>x</code> belong, respectively.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code><b>index class name</b>&amp; operator=(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>a</span><span class=special>=</span><span class=identifier>list</span><span class=special>;</span>
</pre></blockquote>
where <code>a</code> is the <code>multi_index_container</code>
object to which <code>*this</code> belongs.<br>
<b>Returns:</b> <code>*this</code>.<br>
</blockquote>
<code>template &lt;class InputIterator><br>
void assign(InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>clear</span><span class=special>();</span>
@ -437,6 +454,15 @@ index of the <code>multi_index_container</code> to which this index belongs.
</pre></blockquote>
</blockquote>
<code>void assign(std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>assign</span><span class=special>(</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>void assign(size_type n,const value_type&amp; value);</code>
<blockquote>
@ -461,56 +487,113 @@ const_iterator iterator_to(const value_type&amp; x)const;</code>
<h4><a name="capacity">Capacity operations</a></h4>
<code>void resize(size_type n,const value_type&amp; x=value_type());</code>
<code>void resize(size_type n);<br>
void resize(size_type n,const value_type&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&gt;</span><span class=identifier>size</span><span class=special>())</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>n</span><span class=special>-</span><span class=identifier>size</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span>
<span class=keyword>else</span> <span class=keyword>if</span><span class=special>(</span><span class=identifier>n</span><span class=special>&lt;</span><span class=identifier>size</span><span class=special>()){</span>
<span class=identifier>iterator</span> <span class=identifier>it</span><span class=special>=</span><span class=identifier>begin</span><span class=special>();</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>advance</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>n</span><span class=special>);</span>
<span class=identifier>erase</span><span class=special>(</span><span class=identifier>it</span><span class=special>,</span><span class=identifier>end</span><span class=special>());</span>
<span class=special>}</span>
</pre></blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>DefaultInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.<br>
<b>Effects:</b> If <code>size()&lt;n</code>, tries to append <code>n-size()</code> default-inserted
elements (first version) or copies of <code>x</code> (second version) at the end of
the index. If <code>n&lt;size()</code>, erases the last <code>size()-n</code> elements.<br>
<b>Note:</b> If an expansion is requested, the size of the index is not guaranteed
to be <code>n</code> after this operation (other indices may ban insertions.)
</blockquote>
<h4><a name="modifiers">Modifiers</a></h4>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_front(Args&amp;&amp;... args);</code>
<blockquote>
<b>Effects:</b> Inserts <code>x</code> at the beginning of the sequence if
no other index of the <code>multi_index_container</code> bans the insertion.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code>
<code>std::pair&lt;iterator,bool> push_front(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_front(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b> Inserts <code>x</code> at the end of the sequence if
no other index of the <code>multi_index_container</code> bans the insertion.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</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=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>begin</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>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.
</blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace_back(Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>emplace</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>forward</span><span class=special>&lt;</span><span class=identifier>Args</span><span class=special>&gt;(</span><span class=identifier>args</span><span class=special>)...);</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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>
</blockquote>
<code>std::pair&lt;iterator,bool> push_back(const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> push_back(value_type&amp;&amp; x);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</span><span class=special>(),</span><span class=identifier>x</span><span class=special>);</span> <span class=comment>// lvalue ref version</span>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>end</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>x</span><span class=special>));</span> <span class=comment>// rvalue ref version</span>
</pre></blockquote>
<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 took place. On successful
insertion, <code>p.first</code> points to the element inserted; 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>
</blockquote>
<code>template&lt;typename... Args&gt;<br>
std::pair&lt;iterator,bool&gt; emplace(iterator position,Args&amp;&amp;... args);</code>
<blockquote>
<b>Requires:</b> <code>value_type</code> is <code>EmplaceConstructible</code>
into <code>multi_index_container</code> from <code>args</code>.<br>
<b>Effects:</b> Inserts a <code>value_type</code> object constructed with
<code>std::forward&lt;Args&gt;(args)...</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<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 took place. On successful insertion,
<code>p.first</code> points to the element inserted; 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> <code>O(I(n))</code>.<br>
<b>Exception safety:</b> Strong.<br>
</blockquote>
<code>std::pair&lt;iterator,bool> insert(iterator position,const value_type&amp; x);</code><br>
<code>std::pair&lt;iterator,bool> insert(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveInsertable</code>
into <code>multi_index_container</code>.
<code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b> Inserts <code>x</code> before <code>position</code> if insertion
is allowed by all other indices of the <code>multi_index_container</code>.<br>
<b>Returns:</b> The return value is a pair <code>p</code>. <code>p.second</code>
@ -525,7 +608,6 @@ Note that more than one element can be causing insertion not to be allowed.<br>
<code>void insert(iterator position,size_type n,const value_type&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>for</span><span class=special>(</span><span class=identifier>size_type</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=identifier>n</span><span class=special>;++</span><span class=identifier>i</span><span class=special>)</span><span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>x</span><span class=special>);</span>
@ -537,22 +619,31 @@ void insert(iterator position,InputIterator first,InputIterator last);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid iterator of the index.
<code>InputIterator</code> is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">
<code>Input Iterator</code></a> over elements of type
<code>value_type</code> or a type convertible to <code>value_type</code>.
<code>InputIterator</code> is an input iterator.
<code>value_type</code> is
<code>EmplaceConstructible</code> into
<code>multi_index_container</code> from <code>*first</code>.
<code>first</code> and <code>last</code> are not iterators into any
index of the <code>multi_index_container</code> to which this index belongs.
<code>last</code> is reachable from <code>first</code>.<br>
<b>Effects:</b>
<blockquote><pre>
<span class=keyword>while</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=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,*</span><span class=identifier>first</span><span class=special>++);</span>
</pre></blockquote>
For each element of [<code>first</code>, <code>last</code>), in this
order, inserts it before <code>position</code> if insertion is allowed by all
other indices of the <code>multi_index_container</code>.<br>
<b>Complexity:</b> <code>O(m*I(n+m))</code>, where <code>m</code> is the
number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> Basic.
</blockquote>
<code>void insert(iterator position,std::initializer_list&lt;value_type&gt; list);</code>
<blockquote>
<b>Effects:</b>
<blockquote><pre>
<span class=identifier>insert</span><span class=special>(</span><span class=identifier>position</span><span class=special>,</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>list</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
</blockquote>
<code>iterator erase(iterator position);</code>
<blockquote>
@ -578,11 +669,14 @@ the number of elements in [<code>first</code>,<code>last</code>).<br>
<b>Exception safety:</b> <code>nothrow</code>.<br>
</blockquote>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a>
<a name="replace"><code>bool replace(iterator position,const value_type&amp; x);</code></a><br>
<code>bool replace(iterator position,value_type&amp;&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>position</code> is a valid dereferenceable iterator
of the index.<br>
<b>Requires (first version):</b> <code>value_type</code> is <code>CopyAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Requires (second version):</b> <code>value_type</code> is <code>MoveAssignable</code>.
<code>position</code> is a valid dereferenceable iterator of the index.<br>
<b>Effects:</b> Assigns the value <code>x</code> to the element pointed
to by <code>position</code> into the <code>multi_index_container</code> to which
the index belongs if replacing is allowed by all other indices of the
@ -601,9 +695,8 @@ belongs remains in its original state.
<code>template&lt;typename Modifier> bool modify(iterator position,Modifier mod);</code></a>
<blockquote>
<b>Requires:</b> <code>Modifier</code> is a model of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> is a unary function object
accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index.<br>
<b>Effects:</b> Calls <code>mod(e)</code> where <code>e</code> is the element
@ -626,9 +719,8 @@ the element pointed to by <code>position</code> is erased.
bool modify(iterator position,Modifier mod,Rollback back);</code>
<blockquote>
<b>Requires:</b> <code>Modifier</code> and <code>Rollback</code> are models of
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">
<code>Unary Function</code></a> accepting arguments of type
<b>Requires:</b> <code>mod</code> and <code>back</code> are unary function
objects accepting arguments of type
<code>value_type&amp;</code>. <code>position</code> is a valid dereferenceable
iterator of the index. The sequence of operations <code>mod(e)</code>,
<code>back(e)</code>, where <code>e</code> is the element
@ -761,11 +853,10 @@ is the number of elements erased.<br>
<code>void merge(index class name&amp; x);</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
<b>Requires:</b> <code>std::less&lt;value_type&gt;</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&lt;value_type></code>.<br>
<code>std::less&lt;value_type&gt;</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
@ -782,12 +873,11 @@ references is preserved.<br>
otherwise, basic.<br>
</blockquote>
<code>template &lt;typename Compare> void merge(index class name&amp; x,Compare comp);</code>
<code>template &lt;typename Compare&gt; void merge(index class name&amp; x,Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.
<b>Requires:</b> <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>).
@ -808,24 +898,22 @@ otherwise, basic.<br>
<code>void sort();</code>
<blockquote>
<b>Requires:</b> <code>std::less&lt;value_type></code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Requires:</b> <code>std::less&lt;value_type&gt;</code> induces a
strict weark ordering over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to
<code>std::less&lt;value_type></code>. The sorting is stable, i.e.
<code>std::less&lt;value_type&gt;</code>. The sorting is stable, i.e.
equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
<b>Complexity:</b> <code>O(n*log(n))</code>.<br>
<b>Exception safety:</b> <code>nothrow</code> if
<code>std::less&lt;value_type></code> does not throw; otherwise, basic.
<code>std::less&lt;value_type&gt;</code> does not throw; otherwise, basic.
</blockquote>
<code>template &lt;typename Compare> void sort(Compare comp);</code>
<code>template &lt;typename Compare&gt; void sort(Compare comp);</code>
<blockquote>
<b>Requires:</b> <code>Compare</code> is a
<a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">
<code>Strict Weak Ordering</code></a> over <code>value_type</code>.<br>
<b>Requires:</b> <code>Compare</code> induces a
strict weak ordering over <code>value_type</code>.<br>
<b>Effects:</b> Sorts the index according to <code>comp</code>. The sorting
is stable, i.e. equivalent elements preserve their relative position.<br>
<b>Postconditions:</b> Validity of iterators and references is preserved.<br>
@ -955,9 +1043,9 @@ Random access indices
<br>
<p>Revised July 21st 2009</p>
<p>Revised July 8th 2013</p>
<p>&copy; Copyright 2003-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -27,10 +27,10 @@ Acknowledgements
<hr>
<h2>Contents</h2>
<ul>
<li><a href="#boost_1_55">Boost 1.55 release</a></li>
<li><a href="#boost_1_54">Boost 1.54 release</a></li>
<li><a href="#boost_1_49">Boost 1.49 release</a></li>
<li><a href="#boost_1_48">Boost 1.48 release</a></li>
@ -48,6 +48,39 @@ Acknowledgements
<li><a href="#boost_1_33">Boost 1.33 release</a></li>
</ul>
<h2><a name="boost_1_55">Boost 1.55 release</a></h2>
<p>
<ul>
<li>Boost.MultiIndex has been brought to a higher level of compliance
with C++11.
<ul>
<li><code>multi_index_container</code> is now efficiently movable.</li>
<li>Initializer lists supported.</li>
<li>Emplace functions provided.</li>
<li>Non-copyable elements (such as <code>std::unique_ptr&lt;T&gt;</code>) supported. This includes
insertion of a range [<code>first</code>,<code>last</code>) where the iterators point to a type that is
convertible to that of the element: no copy construction happens in the process.
</li>
<li>Random access indices provide <code>shrink_to_fit()</code>.</li>
</ul>
Refer to the <a href="compiler_specifics.html">compiler specifics</a> section for limitations
on pre-C++11 compilers.
</li>
<li>The following classes are deprecated:
<ul>
<li><a href="reference/key_extraction.html#member_offset"><code>member_offset</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>const_mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#const_mem_fun_explicit"><code>mem_fun_explicit</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_equal_to"><code>composite_key_result_equal_to</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_less"><code>composite_key_result_less</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_greater"><code>composite_key_result_greater</code></a>,</li>
<li><a href="reference/key_extraction.html#composite_key_result_hash"><code>composite_key_result_hash</code></a>.</li>
</ul>
</li>
<li>Maintenance fixes.</li>
</ul>
</p>
<h2><a name="boost_1_54">Boost 1.54 release</a></h2>
<p>
@ -371,7 +404,7 @@ Acknowledgements
<br>
<p>Revised February 21st 2013</p>
<p>Revised July 9st 2013</p>
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@ -222,9 +222,8 @@ element.
<p>
The hash function is the very core of the fast lookup capabilities of this type of
indices: a hasher
is just a <a href="http://www.sgi.com/tech/stl/UnaryFunction.html"><code>Unary
Function</code></a> returning an <code>std::size_t</code> value for any given
indices: a hasher is just a unary function object
returning an <code>std::size_t</code> value for any given
key. In general, it is impossible that every key map to a different hash value, for
the space of keys can be greater than the number of permissible hash codes: what
makes for a good hasher is that the probability of a collision (two different
@ -561,7 +560,7 @@ container:
<span class=identifier>std</span><span class=special>::</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>reference_wrapper</span><span class=special>&lt;</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&gt;</span> <span class=special>&gt;</span> <span class=identifier>v</span><span class=special>;</span>
<span class=identifier>BOOST_FOREACH</span><span class=special>(</span><span class=keyword>const</span> <span class=keyword>int</span><span class=special>&amp;</span> <span class=identifier>i</span><span class=special>,</span><span class=identifier>c</span><span class=special>)</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>push_back</span><span class=special>(</span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>cref</span><span class=special>(</span><span class=identifier>i</span><span class=special>));</span>
<span class=comment>// this compiles OK, as reference_wrappers are assignable</span>
<span class=comment>// this compiles OK, as reference_wrappers are swappable</span>
<span class=identifier>std</span><span class=special>::</span><span class=identifier>random_shuffle</span><span class=special>(</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>begin</span><span class=special>(),</span><span class=identifier>v</span><span class=special>.</span><span class=identifier>end</span><span class=special>());</span>
</pre></blockquote>
@ -569,9 +568,8 @@ container:
Elements of <code>v</code> are <code>reference_wrapper</code>s (from
<a href="../../../../doc/html/ref.html">Boost.Ref</a>) to the actual elements
in the multi-index container. These objects still do not allow modification
of the referenced entities, but they are
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>,
which is the only requirement <code>std::random_suffle</code> imposes. Once
of the referenced entities, but they are swappable,
which is the only requirement <code>std::random_shuffle</code> imposes. Once
we have our desired rearrange stored in the view, we can transfer it to
the container with
</p>
@ -718,9 +716,9 @@ Key extraction
<br>
<p>Revised October 15th 2007</p>
<p>Revised July 7th 2013</p>
<p>&copy; Copyright 2003-2007 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2003-2013 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;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">

View File

@ -0,0 +1,34 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
namespace boost{
namespace multi_index{
namespace detail{
/* Used to mark a special ctor variant that copies the internal objects of
* a container but not its elements.
*/
struct do_not_copy_elements_tag{};
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -14,11 +14,15 @@
#endif
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/call_traits.hpp>
#include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/multi_index/detail/copy_map.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/node_type.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index_container_fwd.hpp>
#include <boost/tuple/tuple.hpp>
#include <utility>
@ -42,6 +46,10 @@ namespace detail{
* cannot be called directly from the index classes.)
*/
struct lvalue_tag{};
struct rvalue_tag{};
struct emplaced_tag{};
template<typename Value,typename IndexSpecifierList,typename Allocator>
class index_base
{
@ -74,27 +82,61 @@ protected:
#endif
private:
typedef typename call_traits<Value>::param_type value_param_type;
typedef Value value_type;
protected:
explicit index_base(const ctor_args_list&,const Allocator&){}
index_base(
const index_base<Value,IndexSpecifierList,Allocator>&,
do_not_copy_elements_tag)
{}
void copy_(
const index_base<Value,IndexSpecifierList,Allocator>&,const copy_map_type&)
{}
node_type* insert_(value_param_type v,node_type* x)
node_type* insert_(const value_type& v,node_type* x,lvalue_tag)
{
boost::detail::allocator::construct(&x->value(),v);
return x;
}
node_type* insert_(value_param_type v,node_type*,node_type* x)
node_type* insert_(const value_type& v,node_type* x,rvalue_tag)
{
/* This shoud have used a modified, T&&-compatible version of
* boost::detail::allocator::construct, but
* <boost/detail/allocator_utilities.hpp> is too old and venerable to mess
* with; besides, it is a general internal utility and the imperfect
* perfect forwarding emulation of Boost.Move might break other libs.
*/
new (&x->value()) value_type(boost::move(const_cast<value_type&>(v)));
return x;
}
node_type* insert_(const value_type&,node_type* x,emplaced_tag)
{
return x;
}
node_type* insert_(const value_type& v,node_type*,node_type* x,lvalue_tag)
{
boost::detail::allocator::construct(&x->value(),v);
return x;
}
node_type* insert_(const value_type& v,node_type*,node_type* x,rvalue_tag)
{
new (&x->value()) value_type(boost::move(const_cast<value_type&>(v)));
return x;
}
node_type* insert_(const value_type&,node_type*,node_type* x,emplaced_tag)
{
return x;
}
void erase_(node_type* x)
{
boost::detail::allocator::destroy(&x->value());
@ -109,12 +151,20 @@ protected:
void swap_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(index_base<Value,IndexSpecifierList,Allocator>&){}
bool replace_(const value_type& v,node_type* x,lvalue_tag)
{
x->value()=v;
return true;
}
bool replace_(const value_type& v,node_type* x,rvalue_tag)
{
x->value()=boost::move(const_cast<value_type&>(v));
return true;
}
bool modify_(node_type*){return true;}
bool modify_rollback_(node_type*){return true;}
@ -146,11 +196,39 @@ protected:
std::size_t final_size_()const{return final().size_();}
std::size_t final_max_size_()const{return final().max_size_();}
std::pair<final_node_type*,bool> final_insert_(value_param_type x)
std::pair<final_node_type*,bool> final_insert_(const value_type& x)
{return final().insert_(x);}
std::pair<final_node_type*,bool> final_insert_rv_(const value_type& x)
{return final().insert_rv_(x);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(T& t)
{return final().insert_ref_(t);}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
std::pair<final_node_type*,bool> final_insert_(
value_param_type x,final_node_type* position)
const value_type& x,final_node_type* position)
{return final().insert_(x,position);}
std::pair<final_node_type*,bool> final_insert_rv_(
const value_type& x,final_node_type* position)
{return final().insert_rv_(x,position);}
template<typename T>
std::pair<final_node_type*,bool> final_insert_ref_(
T& t,final_node_type* position)
{return final().insert_ref_(t,position);}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<final_node_type*,bool> final_emplace_hint_(
final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return final().emplace_hint_(
position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
void final_erase_(final_node_type* x){final().erase_(x);}
@ -159,9 +237,13 @@ protected:
void final_clear_(){final().clear_();}
void final_swap_(final_type& x){final().swap_(x);}
bool final_replace_(
value_param_type k,final_node_type* x)
const value_type& k,final_node_type* x)
{return final().replace_(k,x);}
bool final_replace_rv_(
const value_type& k,final_node_type* x)
{return final().replace_rv_(k,x);}
template<typename Modifier>
bool final_modify_(Modifier& mod,final_node_type* x)

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2008 Joaquin M Lopez Munoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -74,12 +74,12 @@ public:
void reserve(std::size_t c)
{
if(c>capacity_){
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
node_impl_type::transfer(begin(),end()+1,spc1.data());
spc.swap(spc1);
capacity_=c;
}
if(c>capacity_)set_capacity(c);
}
void shrink_to_fit()
{
if(capacity_>size_)set_capacity(size_);
}
pointer begin()const{return ptrs();}
@ -124,6 +124,14 @@ private:
{
return spc.data();
}
void set_capacity(std::size_t c)
{
auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
node_impl_type::transfer(begin(),end()+1,spc1.data());
spc.swap(spc1);
capacity_=c;
}
};
template<typename Allocator>

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -14,6 +14,7 @@
#endif
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/mpl/if.hpp>
namespace boost{

View File

@ -0,0 +1,247 @@
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/multi_index for library home page.
*/
#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
/* Utilities for emulation of variadic template functions. Variadic packs are
* replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters:
*
* - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK
* - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK
* - std::forward<Args>(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK
*
* Forwarding emulated with Boost.Move. A template functions foo_imp
* defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
* arguments: variable number of arguments is emulated by providing a set of
* overloads foo forwarding to foo_impl with
*
* BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg)
*
* which fill the extra args with boost::multi_index::detail::noarg's.
* boost::multi_index::detail::vartempl_placement_new works the opposite
* way: it acceps a full a pointer x to Value and a
* BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to
* new(x) Value(args) where args is the argument pack after discarding
* noarg's.
*
* Emulation decays to the real thing when the compiler supports variadic
* templates and move semantics natively.
*/
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\
defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/logical/and.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS)
#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5
#endif
#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \
BOOST_PP_ENUM_PARAMS( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T)
#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \
BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n)
#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \
BOOST_PP_ENUM( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
BOOST_MULTI_INDEX_VARTEMPL_ARG,~)
#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \
boost::forward<BOOST_PP_CAT(T,n)>(BOOST_PP_CAT(t,n))
#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \
BOOST_PP_ENUM( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)
namespace boost{namespace multi_index{namespace detail{
struct noarg{};
}}}
/* call vartempl function without args */
#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \
BOOST_PP_ENUM_PARAMS( \
BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT)
#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \
template<BOOST_PP_ENUM_PARAMS(n,typename T)>
#define BOOST_MULTI_INDEX_TEMPLATE_0(n)
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \
BOOST_PP_IF(n, \
BOOST_MULTI_INDEX_TEMPLATE_N, \
BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
{ \
return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_AND( \
n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
ret,name_from,name_to) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \
(ret)(name_from)(name_to))
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \
z,n,data) \
BOOST_PP_IF(n, \
BOOST_MULTI_INDEX_TEMPLATE_N, \
BOOST_MULTI_INDEX_TEMPLATE_0)(n) \
BOOST_PP_SEQ_ELEM(0,data) /* ret */ \
BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \
BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \
{ \
return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \
BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \
); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
ret,name_from,name_to,extra_arg_type,extra_arg_name) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \
(ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name))
namespace boost{
namespace multi_index{
namespace detail{
#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \
template< \
typename Value \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM_PARAMS(n,typename T) \
> \
Value* name( \
Value* x \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \
BOOST_PP_COMMA_IF( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \
BOOST_PP_ENUM_PARAMS( \
BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \
BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \
{ \
return new(x) Value( \
BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \
}
#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \
BOOST_PP_REPEAT_FROM_TO( \
0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \
BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \
name)
BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new)
#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX
#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#else
/* native variadic templates support */
#include <utility>
#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args
#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args
#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward<Args>(args)...
#define BOOST_MULTI_INDEX_NULL_PARAM_PACK
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \
ret,name_from,name_to) \
template<typename... Args> ret name_from(Args&&... args) \
{ \
return name_to(std::forward<Args>(args)...); \
}
#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \
ret,name_from,name_to,extra_arg_type,extra_arg_name) \
template<typename... Args> ret name_from( \
extra_arg_type extra_arg_name,Args&&... args) \
{ \
return name_to(extra_arg_name,std::forward<Args>(args)...); \
}
namespace boost{
namespace multi_index{
namespace detail{
template<typename Value,typename... Args>
Value* vartempl_placement_new(Value*x,Args&&... args)
{
return new(x) Value(std::forward<Args>(args)...);
}
} /* namespace multi_index::detail */
} /* namespace multi_index */
} /* namespace boost */
#endif
#endif

View File

@ -21,33 +21,43 @@
#include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp>
#include <boost/limits.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/auto_space.hpp>
#include <boost/multi_index/detail/bucket_array.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/hash_index_iterator.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/hashed_index_fwd.hpp>
#include <boost/tuple/tuple.hpp>
#include <cstddef>
#include <functional>
#include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/serialization/nvp.hpp>
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&hashed_index::check_invariant_); \
detail::make_obj_guard(x,&hashed_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this)
#else
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
#endif
@ -191,6 +201,12 @@ private:
typedef typename call_traits<
key_type>::param_type key_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public:
/* construct/destroy/copy
@ -205,6 +221,15 @@ public:
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
allocator_type get_allocator()const
{
return this->final().get_allocator();
@ -248,14 +273,27 @@ public:
/* modifiers */
std::pair<iterator,bool> insert(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace,emplace_impl)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
iterator,emplace_hint,emplace_hint_impl,iterator,position)
std::pair<iterator,bool> insert(const value_type& x)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,value_param_type x)
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -265,14 +303,30 @@ public:
return make_iterator(p.first);
}
iterator insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(
x,static_cast<final_node_type*>(position.get_node()));
return make_iterator(p.first);
}
template<typename InputIterator>
void insert(InputIterator first,InputIterator last)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
iterator hint=end();
for(;first!=last;++first)hint=insert(hint,*first);
for(;first!=last;++first)this->final_insert_ref_(*first);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(std::initializer_list<value_type> list)
{
insert(list.begin(),list.end());
}
#endif
iterator erase(iterator position)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -325,7 +379,7 @@ public:
return first;
}
bool replace(iterator position,value_param_type x)
bool replace(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -335,6 +389,16 @@ public:
x,static_cast<final_node_type*>(position.get_node()));
}
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier>
bool modify(iterator position,Modifier mod)
{
@ -410,6 +474,7 @@ public:
void swap(hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final());
}
@ -634,6 +699,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
*/
}
hashed_index(
const hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x,
do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
key(x.key),
hash_(x.hash_),
eq_(x.eq_),
buckets(x.get_allocator(),header()->impl(),0),
mlf(1.0f),
first_bucket(buckets.size())
{
calculate_max_load();
}
~hashed_index()
{
/* the container is guaranteed to be empty by now */
@ -689,8 +773,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map);
}
node_type* insert_(value_param_type v,node_type* x)
template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{
reserve(size()+1);
@ -698,7 +783,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_impl_pointer pos=buckets.at(buc);
if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
node_type* res=static_cast<node_type*>(super::insert_(v,x));
node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x){
link(x,pos);
if(first_bucket>buc)first_bucket=buc;
@ -706,7 +791,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
return res;
}
node_type* insert_(value_param_type v,node_type* position,node_type* x)
template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{
reserve(size()+1);
@ -714,7 +801,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
node_impl_pointer pos=buckets.at(buc);
if(!link_point(v,pos,Category()))return node_type::from_impl(pos);
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x){
link(x,pos);
if(first_bucket>buc)first_bucket=buc;
@ -776,10 +864,26 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x);
}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(
hashed_index<KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>& x)
{
buckets.swap(x.buckets);
std::swap(mlf,x.mlf);
std::swap(max_load,x.max_load);
std::swap(first_bucket,x.first_bucket);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
if(eq_(key(v),key(x->value()))){
return super::replace_(v,x);
return super::replace_(v,x,variant);
}
node_impl_pointer y=prev(x);
@ -788,7 +892,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
BOOST_TRY{
std::size_t buc=find_bucket(v);
node_impl_pointer pos=buckets.at(buc);
if(link_point(v,pos,Category())&&super::replace_(v,x)){
if(link_point(v,pos,Category())&&super::replace_(v,x,variant)){
link(x,pos);
if(first_bucket>buc){
first_bucket=buc;
@ -1157,6 +1261,29 @@ private:
}
#endif
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
iterator emplace_hint_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return make_iterator(p.first);
}
key_from_value key;
hasher hash_;
key_equal eq_;
@ -1257,5 +1384,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
}
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF
#endif

View File

@ -47,11 +47,13 @@
#include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/modify_key_adaptor.hpp>
#include <boost/multi_index/detail/ord_index_node.hpp>
@ -61,12 +63,17 @@
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/unbounded.hpp>
#include <boost/multi_index/detail/value_compare.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/ordered_index_fwd.hpp>
#include <boost/ref.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_same.hpp>
#include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/archive/archive_exception.hpp>
#include <boost/bind.hpp>
@ -75,11 +82,14 @@
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&ordered_index::check_invariant_); \
detail::make_obj_guard(x,&ordered_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this)
#else
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
#endif
@ -217,6 +227,12 @@ private:
typedef typename call_traits<
key_type>::param_type key_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public:
/* construct/copy/destroy
@ -231,6 +247,15 @@ public:
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
allocator_type get_allocator()const
{
return this->final().get_allocator();
@ -269,14 +294,27 @@ public:
/* modifiers */
std::pair<iterator,bool> insert(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace,emplace_impl)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
iterator,emplace_hint,emplace_hint_impl,iterator,position)
std::pair<iterator,bool> insert(const value_type& x)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,value_param_type x)
std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
iterator insert(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -286,14 +324,35 @@ public:
return make_iterator(p.first);
}
iterator insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(
x,static_cast<final_node_type*>(position.get_node()));
return make_iterator(p.first);
}
template<typename InputIterator>
void insert(InputIterator first,InputIterator last)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
iterator hint=end();
for(;first!=last;++first)hint=insert(hint,*first);
node_type* hint=header(); /* end() */
for(;first!=last;++first){
hint=this->final_insert_ref_(
*first,static_cast<final_node_type*>(hint)).first;
node_type::increment(hint);
}
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(std::initializer_list<value_type> list)
{
insert(list.begin(),list.end());
}
#endif
iterator erase(iterator position)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -330,7 +389,7 @@ public:
return first;
}
bool replace(iterator position,value_param_type x)
bool replace(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -340,6 +399,16 @@ public:
x,static_cast<final_node_type*>(position.get_node()));
}
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier>
bool modify(iterator position,Modifier mod)
{
@ -409,6 +478,7 @@ public:
void swap(ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final());
}
@ -551,10 +621,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
comp_(x.comp_)
{
/* Copy ctor just takes the key and compare objects from x. The rest is
* done in subsequent call to copy_().
* done in a subsequent call to copy_().
*/
}
ordered_index(
const ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x,
do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
key(x.key),
comp_(x.comp_)
{
empty_initialize();
}
~ordered_index()
{
/* the container is guaranteed to be empty by now */
@ -623,28 +708,31 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map);
}
node_type* insert_(value_param_type v,node_type* x)
template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{
link_info inf;
if(!link_point(key(v),inf,Category())){
return node_type::from_impl(inf.pos);
}
node_type* res=static_cast<node_type*>(super::insert_(v,x));
node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
}
return res;
}
node_type* insert_(value_param_type v,node_type* position,node_type* x)
template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{
link_info inf;
if(!hinted_link_point(key(v),position,inf,Category())){
return node_type::from_impl(inf.pos);
}
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
node_type* res=static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
}
@ -689,10 +777,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x);
}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(
ordered_index<KeyFromValue,Compare,SuperMeta,TagList,Category>& x)
{
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
if(in_place(v,x,Category())){
return super::replace_(v,x);
return super::replace_(v,x,variant);
}
node_type* next=x;
@ -703,7 +802,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
BOOST_TRY{
link_info inf;
if(link_point(key(v),inf,Category())&&super::replace_(v,x)){
if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){
node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl());
return true;
}
@ -1085,6 +1184,29 @@ private:
}
#endif
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
iterator emplace_hint_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool>p=
this->final_emplace_hint_(
static_cast<final_node_type*>(position.get_node()),
BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
return make_iterator(p.first);
}
template<typename LowerBounder,typename UpperBounder>
std::pair<iterator,iterator>
range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const
@ -1402,5 +1524,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
}
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF
#endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -20,10 +20,13 @@
#include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/rnd_node_iterator.hpp>
#include <boost/multi_index/detail/rnd_index_node.hpp>
@ -32,6 +35,7 @@
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/random_access_index_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp>
@ -41,17 +45,24 @@
#include <stdexcept>
#include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include<initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/bind.hpp>
#include <boost/multi_index/detail/rnd_index_loader.hpp>
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&random_access_index::check_invariant_); \
detail::make_obj_guard(x,&random_access_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this)
#else
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
#endif
@ -176,6 +187,12 @@ private:
typedef typename call_traits<
value_type>::param_type value_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public:
/* construct/copy/destroy
@ -190,12 +207,28 @@ public:
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
random_access_index<SuperMeta,TagList>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
template <class InputIterator>
void assign(InputIterator first,InputIterator last)
{
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void assign(std::initializer_list<value_type> list)
{
assign(list.begin(),list.end());
}
#endif
void assign(size_type n,value_param_type value)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
@ -241,12 +274,32 @@ public:
size_type size()const{return this->final_size_();}
size_type max_size()const{return this->final_max_size_();}
size_type capacity()const{return ptrs.capacity();}
void reserve(size_type n){ptrs.reserve(n);}
void resize(size_type n,value_param_type x=value_type())
void reserve(size_type n)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())insert(end(),n-size(),x);
ptrs.reserve(n);
}
void shrink_to_fit()
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
ptrs.shrink_to_fit();
}
void resize(size_type n)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())
for(size_type m=n-size();m--;)
this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
else if(n<size())erase(begin()+n,end());
}
void resize(size_type n,value_param_type x)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
if(n>size())for(size_type m=n-size();m--;)this->final_insert_(x);
else if(n<size())erase(begin()+n,end());
}
@ -271,14 +324,28 @@ public:
/* modifiers */
std::pair<iterator,bool> push_front(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_front,emplace_front_impl)
std::pair<iterator,bool> push_front(const value_type& x)
{return insert(begin(),x);}
std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
{return insert(begin(),boost::move(x));}
void pop_front(){erase(begin());}
std::pair<iterator,bool> push_back(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_back,emplace_back_impl)
std::pair<iterator,bool> push_back(const value_type& x)
{return insert(end(),x);}
std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
{return insert(end(),boost::move(x));}
void pop_back(){erase(--end());}
std::pair<iterator,bool> insert(iterator position,value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
emplace_return_type,emplace,emplace_impl,iterator,position)
std::pair<iterator,bool> insert(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -290,6 +357,18 @@ public:
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
if(p.second&&position.get_node()!=header()){
relocate(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
void insert(iterator position,size_type n,value_param_type x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -315,6 +394,13 @@ public:
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(iterator position,std::initializer_list<value_type> list)
{
insert(position,list.begin(),list.end());
}
#endif
iterator erase(iterator position)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -339,7 +425,7 @@ public:
return last;
}
bool replace(iterator position,value_param_type x)
bool replace(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -349,6 +435,16 @@ public:
x,static_cast<final_node_type*>(position.get_node()));
}
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier>
bool modify(iterator position,Modifier mod)
{
@ -394,6 +490,7 @@ public:
void swap(random_access_index<SuperMeta,TagList>& x)
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final());
}
@ -638,6 +735,18 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
*/
}
random_access_index(
const random_access_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag()),
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super(),
#endif
ptrs(x.get_allocator(),header()->impl(),0)
{
}
~random_access_index()
{
/* the container is guaranteed to be empty by now */
@ -671,18 +780,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map);
}
node_type* insert_(value_param_type v,node_type* x)
template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{
ptrs.room_for_one();
node_type* res=static_cast<node_type*>(super::insert_(v,x));
node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x)ptrs.push_back(x->impl());
return res;
}
node_type* insert_(value_param_type v,node_type* position,node_type* x)
template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{
ptrs.room_for_one();
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x)ptrs.push_back(x->impl());
return res;
}
@ -726,9 +839,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x);
}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(random_access_index<SuperMeta,TagList>& x)
{
return super::replace_(v,x);
ptrs.swap(x.ptrs);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
return super::replace_(v,x,variant);
}
bool modify_(node_type* x)
@ -842,7 +967,7 @@ private:
{
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
clear();
for(;first!=last;++first)push_back(*first);
for(;first!=last;++first)this->final_insert_ref_(*first);
}
void assign_iter(size_type n,value_param_type value,mpl::false_)
@ -860,7 +985,7 @@ private:
size_type s=0;
BOOST_TRY{
for(;first!=last;++first){
if(push_back(*first).second)++s;
if(this->final_insert_ref_(*first).second)++s;
}
}
BOOST_CATCH(...){
@ -891,6 +1016,35 @@ private:
relocate(position,end()-s,end());
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_front_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_back_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
if(p.second&&position.get_node()!=header()){
relocate(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
ptr_array ptrs;
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
@ -1015,5 +1169,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
}
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF
#endif

View File

@ -1,4 +1,4 @@
/* Copyright 2003-2011 Joaquin M Lopez Munoz.
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -20,17 +20,21 @@
#include <boost/detail/workaround.hpp>
#include <boost/foreach_fwd.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/bidir_node_iterator.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/index_node_base.hpp>
#include <boost/multi_index/detail/safe_ctr_proxy.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/seq_index_node.hpp>
#include <boost/multi_index/detail/seq_index_ops.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/multi_index/sequenced_index_fwd.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_integral.hpp>
@ -38,16 +42,23 @@
#include <functional>
#include <utility>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include<initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/bind.hpp>
#endif
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&sequenced_index::check_invariant_); \
detail::make_obj_guard(x,&sequenced_index::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this)
#else
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
#endif
@ -166,6 +177,12 @@ private:
typedef typename call_traits<value_type>::param_type value_param_type;
/* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL
* expansion.
*/
typedef std::pair<iterator,bool> emplace_return_type;
public:
/* construct/copy/destroy
@ -180,12 +197,28 @@ public:
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
sequenced_index<SuperMeta,TagList>& operator=(
std::initializer_list<value_type> list)
{
this->final()=list;
return *this;
}
#endif
template <class InputIterator>
void assign(InputIterator first,InputIterator last)
{
assign_iter(first,last,mpl::not_<is_integral<InputIterator> >());
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void assign(std::initializer_list<value_type> list)
{
assign(list.begin(),list.end());
}
#endif
void assign(size_type n,value_param_type value)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
@ -231,22 +264,21 @@ public:
size_type size()const{return this->final_size_();}
size_type max_size()const{return this->final_max_size_();}
void resize(size_type n,value_param_type x=value_type())
void resize(size_type n)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
if(n>size()){
for(size_type m=n-size();m--;)
this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK);
}
else if(n<size()){for(size_type m=size()-n;m--;)pop_back();}
}
void resize(size_type n,value_param_type x)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
if(n>size())insert(end(),n-size(),x);
else if(n<size()){
iterator it;
if(n<=size()/2){
it=begin();
std::advance(it,n);
}
else{
it=end();
for(size_type m=size()-n;m--;--it){}
}
erase(it,end());
}
else if(n<size())for(size_type m=size()-n;m--;)pop_back();
}
/* access: no non-const versions provided as sequenced_index
@ -258,14 +290,28 @@ public:
/* modifiers */
std::pair<iterator,bool> push_front(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_front,emplace_front_impl)
std::pair<iterator,bool> push_front(const value_type& x)
{return insert(begin(),x);}
std::pair<iterator,bool> push_front(BOOST_RV_REF(value_type) x)
{return insert(begin(),boost::move(x));}
void pop_front(){erase(begin());}
std::pair<iterator,bool> push_back(value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL(
emplace_return_type,emplace_back,emplace_back_impl)
std::pair<iterator,bool> push_back(const value_type& x)
{return insert(end(),x);}
std::pair<iterator,bool> push_back(BOOST_RV_REF(value_type) x)
{return insert(end(),boost::move(x));}
void pop_back(){erase(--end());}
std::pair<iterator,bool> insert(iterator position,value_param_type x)
BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG(
emplace_return_type,emplace,emplace_impl,iterator,position)
std::pair<iterator,bool> insert(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
@ -277,6 +323,18 @@ public:
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
std::pair<iterator,bool> insert(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=this->final_insert_rv_(x);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
void insert(iterator position,size_type n,value_param_type x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -291,6 +349,13 @@ public:
insert_iter(position,first,last,mpl::not_<is_integral<InputIterator> >());
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
void insert(iterator position,std::initializer_list<value_type> list)
{
insert(position,list.begin(),list.end());
}
#endif
iterator erase(iterator position)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
@ -315,7 +380,7 @@ public:
return first;
}
bool replace(iterator position,value_param_type x)
bool replace(iterator position,const value_type& x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
@ -325,6 +390,16 @@ public:
x,static_cast<final_node_type*>(position.get_node()));
}
bool replace(iterator position,BOOST_RV_REF(value_type) x)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
return this->final_replace_rv_(
x,static_cast<final_node_type*>(position.get_node()));
}
template<typename Modifier>
bool modify(iterator position,Modifier mod)
{
@ -370,6 +445,7 @@ public:
void swap(sequenced_index<SuperMeta,TagList>& x)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x);
this->final_swap_(x.final());
}
@ -555,8 +631,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
#endif
{
/* The actual copying takes place in subsequent call to copy_().
*/
/* the actual copying takes place in subsequent call to copy_() */
}
sequenced_index(
const sequenced_index<SuperMeta,TagList>& x,do_not_copy_elements_tag):
super(x,do_not_copy_elements_tag())
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
,safe_super()
#endif
{
empty_initialize();
}
~sequenced_index()
@ -591,16 +678,20 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::copy_(x,map);
}
node_type* insert_(value_param_type v,node_type* x)
template<typename Variant>
node_type* insert_(value_param_type v,node_type* x,Variant variant)
{
node_type* res=static_cast<node_type*>(super::insert_(v,x));
node_type* res=static_cast<node_type*>(super::insert_(v,x,variant));
if(res==x)link(x);
return res;
}
node_type* insert_(value_param_type v,node_type* position,node_type* x)
template<typename Variant>
node_type* insert_(
value_param_type v,node_type* position,node_type* x,Variant variant)
{
node_type* res=static_cast<node_type*>(super::insert_(v,position,x));
node_type* res=
static_cast<node_type*>(super::insert_(v,position,x,variant));
if(res==x)link(x);
return res;
}
@ -643,9 +734,19 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
super::swap_(x);
}
bool replace_(value_param_type v,node_type* x)
void swap_elements_(sequenced_index<SuperMeta,TagList>& x)
{
return super::replace_(v,x);
#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE)
safe_super::swap(x);
#endif
super::swap_elements_(x);
}
template<typename Variant>
bool replace_(value_param_type v,node_type* x,Variant variant)
{
return super::replace_(v,x,variant);
}
bool modify_(node_type* x)
@ -781,7 +882,7 @@ private:
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
clear();
for(;first!=last;++first)push_back(*first);
for(;first!=last;++first)this->final_insert_ref_(*first);
}
void assign_iter(size_type n,value_param_type value,mpl::false_)
@ -796,7 +897,13 @@ private:
iterator position,InputIterator first,InputIterator last,mpl::true_)
{
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
for(;first!=last;++first)insert(position,*first);
for(;first!=last;++first){
std::pair<final_node_type*,bool> p=
this->final_insert_ref_(*first);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
}
}
void insert_iter(
@ -807,7 +914,36 @@ private:
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
for(size_type i=0;i<n;++i)insert(position,x);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_front_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_back_impl(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<iterator,bool> emplace_impl(
iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this);
BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT;
std::pair<final_node_type*,bool> p=
this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
if(p.second&&position.get_node()!=header()){
relink(position.get_node(),p.first);
}
return std::pair<iterator,bool>(make_iterator(p.first),p.second);
}
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\
BOOST_WORKAROUND(__MWERKS__,<=0x3003)
#pragma parse_mfunc_templ reset
@ -929,5 +1065,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable(
}
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF
#endif

View File

@ -1,6 +1,6 @@
/* Multiply indexed container.
*
* Copyright 2003-2011 Joaquin M Lopez Munoz.
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -20,6 +20,7 @@
#include <boost/detail/allocator_utilities.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/move/core.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/find_if.hpp>
@ -31,6 +32,7 @@
#include <boost/multi_index/detail/access_specifier.hpp>
#include <boost/multi_index/detail/adl_swap.hpp>
#include <boost/multi_index/detail/base_type.hpp>
#include <boost/multi_index/detail/do_not_copy_elements_tag.hpp>
#include <boost/multi_index/detail/converter.hpp>
#include <boost/multi_index/detail/header_holder.hpp>
#include <boost/multi_index/detail/has_tag.hpp>
@ -38,10 +40,15 @@
#include <boost/multi_index/detail/prevent_eti.hpp>
#include <boost/multi_index/detail/safe_mode.hpp>
#include <boost/multi_index/detail/scope_guard.hpp>
#include <boost/multi_index/detail/vartempl_support.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/base_from_member.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include <boost/multi_index/detail/archive_constructed.hpp>
#include <boost/multi_index/detail/serialization_version.hpp>
@ -54,11 +61,14 @@
#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)
#include <boost/multi_index/detail/invariant_assert.hpp>
#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \
detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \
detail::make_obj_guard(*this,&multi_index_container::check_invariant_); \
detail::make_obj_guard(x,&multi_index_container::check_invariant_); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#define BOOST_MULTI_INDEX_CHECK_INVARIANT \
BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this)
#else
#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x)
#define BOOST_MULTI_INDEX_CHECK_INVARIANT
#endif
@ -66,6 +76,11 @@ namespace boost{
namespace multi_index{
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
#pragma warning(push)
#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */
#endif
template<typename Value,typename IndexSpecifierList,typename Allocator>
class multi_index_container:
private ::boost::base_from_member<
@ -98,6 +113,8 @@ class multi_index_container:
#endif
private:
BOOST_COPYABLE_AND_MOVABLE(multi_index_container)
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename,typename,typename> friend class detail::index_base;
template <typename,typename> friend struct detail::header_holder;
@ -171,21 +188,28 @@ public:
/* construct/copy/destroy */
/* Do not merge this ctor with the following waiting for resolution of
* EWG issue 2193.
*/
multi_index_container():
bfm_allocator(allocator_type()),
super(ctor_args_list(),bfm_allocator::member),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
explicit multi_index_container(
const ctor_args_list& args_list,
#if BOOST_WORKAROUND(__IBMCPP__,<=600)
/* VisualAge seems to have an ETI issue with the default values
* for arguments args_list and al.
*/
/* VisualAge seems to have an ETI issue with the default value of al */
const ctor_args_list& args_list=
typename mpl::identity<multi_index_container>::type::
ctor_args_list(),
const allocator_type& al=
typename mpl::identity<multi_index_container>::type::
allocator_type()):
#else
const ctor_args_list& args_list=ctor_args_list(),
const allocator_type& al=allocator_type()):
#endif
@ -203,7 +227,7 @@ public:
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
template<typename InputIterator>
multi_index_container(
InputIterator first,InputIterator last,
@ -232,7 +256,9 @@ public:
BOOST_TRY{
iterator hint=super::end();
for(;first!=last;++first){
hint=super::make_iterator(insert_(*first,hint.get_node()).first);
hint=super::make_iterator(
insert_ref_(*first,hint.get_node()).first);
++hint;
}
}
BOOST_CATCH(...){
@ -242,6 +268,34 @@ public:
BOOST_CATCH_END
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container(
std::initializer_list<Value> list,
const ctor_args_list& args_list=ctor_args_list(),
const allocator_type& al=allocator_type()):
bfm_allocator(al),
super(args_list,bfm_allocator::member),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
BOOST_TRY{
typedef typename std::initializer_list<Value>::iterator init_iterator;
iterator hint=super::end();
for(init_iterator first=list.begin(),last=list.end();
first!=last;++first){
hint=super::make_iterator(insert_(*first,hint.get_node()).first);
++hint;
}
}
BOOST_CATCH(...){
clear_();
BOOST_RETHROW;
}
BOOST_CATCH_END
}
#endif
multi_index_container(
const multi_index_container<Value,IndexSpecifierList,Allocator>& x):
bfm_allocator(x.bfm_allocator::member),
@ -264,19 +318,70 @@ public:
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
multi_index_container(BOOST_RV_REF(multi_index_container) x):
bfm_allocator(x.bfm_allocator::member),
bfm_header(),
super(x,detail::do_not_copy_elements_tag()),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x);
swap_elements_(x);
}
~multi_index_container()
{
delete_all_nodes_();
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
/* As per http://www.boost.org/doc/html/move/emulation_limitations.html
* #move.emulation_limitations.assignment_operator
*/
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
multi_index_container<Value,IndexSpecifierList,Allocator> x)
const multi_index_container<Value,IndexSpecifierList,Allocator>& x)
{
multi_index_container y(x);
this->swap(y);
return *this;
}
#endif
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
BOOST_COPY_ASSIGN_REF(multi_index_container) x)
{
multi_index_container y(x);
this->swap(y);
return *this;
}
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
BOOST_RV_REF(multi_index_container) x)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
this->swap(x);
return *this;
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
std::initializer_list<Value> list)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
typedef typename std::initializer_list<Value>::iterator init_iterator;
multi_index_container x(*this,detail::do_not_copy_elements_tag());
iterator hint=x.end();
for(init_iterator first=list.begin(),last=list.end();
first!=last;++first){
hint=x.make_iterator(x.insert_(*first,hint.get_node()).first);
++hint;
}
x.swap_elements_(*this);
return*this;
}
#endif
allocator_type get_allocator()const
{
return allocator_type(bfm_allocator::member);
@ -450,6 +555,19 @@ public:
BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
typedef typename super::copy_map_type copy_map_type;
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
multi_index_container(
const multi_index_container<Value,IndexSpecifierList,Allocator>& x,
detail::do_not_copy_elements_tag):
bfm_allocator(x.bfm_allocator::member),
bfm_header(),
super(x,detail::do_not_copy_elements_tag()),
node_count(0)
{
BOOST_MULTI_INDEX_CHECK_INVARIANT;
}
#endif
node_type* header()const
{
return &*bfm_header::member;
@ -481,11 +599,119 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
return static_cast<std::size_t >(-1);
}
std::pair<node_type*,bool> insert_(const Value& v)
template<typename Variant>
std::pair<node_type*,bool> insert_(const Value& v,Variant variant)
{
node_type* x=allocate_node();
BOOST_TRY{
node_type* res=super::insert_(v,x);
node_type* res=super::insert_(v,x,variant);
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_(const Value& v)
{
return insert_(v,detail::lvalue_tag());
}
std::pair<node_type*,bool> insert_rv_(const Value& v)
{
return insert_(v,detail::rvalue_tag());
}
template<typename T>
std::pair<node_type*,bool> insert_ref_(T& t)
{
node_type* x=allocate_node();
BOOST_TRY{
new(&x->value()) value_type(t);
BOOST_TRY{
node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_ref_(const value_type& x)
{
return insert_(x);
}
std::pair<node_type*,bool> insert_ref_(value_type& x)
{
return insert_(x);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<node_type*,bool> emplace_(
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
node_type* x=allocate_node();
BOOST_TRY{
detail::vartempl_placement_new(
&x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
BOOST_TRY{
node_type* res=super::insert_(x->value(),x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
template<typename Variant>
std::pair<node_type*,bool> insert_(
const Value& v,node_type* position,Variant variant)
{
node_type* x=allocate_node();
BOOST_TRY{
node_type* res=super::insert_(v,position,x,variant);
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
@ -503,18 +729,87 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
}
std::pair<node_type*,bool> insert_(const Value& v,node_type* position)
{
return insert_(v,position,detail::lvalue_tag());
}
std::pair<node_type*,bool> insert_rv_(const Value& v,node_type* position)
{
return insert_(v,position,detail::rvalue_tag());
}
template<typename T>
std::pair<node_type*,bool> insert_ref_(
T& t,node_type* position)
{
node_type* x=allocate_node();
BOOST_TRY{
node_type* res=super::insert_(v,position,x);
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
new(&x->value()) value_type(t);
BOOST_TRY{
node_type* res=super::insert_(
x->value(),position,x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
else{
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
BOOST_RETHROW;
}
BOOST_CATCH_END
}
std::pair<node_type*,bool> insert_ref_(
const value_type& x,node_type* position)
{
return insert_(x,position);
}
std::pair<node_type*,bool> insert_ref_(
value_type& x,node_type* position)
{
return insert_(x,position);
}
template<BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK>
std::pair<node_type*,bool> emplace_hint_(
node_type* position,
BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK)
{
node_type* x=allocate_node();
BOOST_TRY{
detail::vartempl_placement_new(
&x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK);
BOOST_TRY{
node_type* res=super::insert_(
x->value(),position,x,detail::emplaced_tag());
if(res==x){
++node_count;
return std::pair<node_type*,bool>(res,true);
}
else{
boost::detail::allocator::destroy(&x->value());
deallocate_node(x);
return std::pair<node_type*,bool>(res,false);
}
}
BOOST_CATCH(...){
boost::detail::allocator::destroy(&x->value());
BOOST_RETHROW;
}
BOOST_CATCH_END
}
BOOST_CATCH(...){
deallocate_node(x);
@ -558,9 +853,22 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS:
std::swap(node_count,x.node_count);
}
void swap_elements_(
multi_index_container<Value,IndexSpecifierList,Allocator>& x)
{
std::swap(bfm_header::member,x.bfm_header::member);
super::swap_elements_(x);
std::swap(node_count,x.node_count);
}
bool replace_(const Value& k,node_type* x)
{
return super::replace_(k,x);
return super::replace_(k,x,detail::lvalue_tag());
}
bool replace_rv_(const Value& k,node_type* x)
{
return super::replace_(k,x,detail::rvalue_tag());
}
template<typename Modifier>
@ -728,6 +1036,10 @@ private:
#endif
};
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
#pragma warning(pop) /* C4522 */
#endif
/* retrieval of indices by number */
template<typename MultiIndexContainer,int N>
@ -1139,5 +1451,6 @@ using multi_index::project;
} /* namespace boost */
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT
#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF
#endif

View File

@ -1,6 +1,6 @@
/* Used in Boost.MultiIndex tests.
*
* Copyright 2003-2008 Joaquin M Lopez Munoz.
* Copyright 2003-2013 Joaquin M Lopez Munoz.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
@ -12,6 +12,8 @@
#define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
@ -36,6 +38,32 @@ struct employee
id(id_),name(name_),age(age_),ssn(ssn_)
{}
employee(const employee& x):
id(x.id),name(x.name),age(x.age),ssn(x.ssn)
{}
employee(BOOST_RV_REF(employee) x):
id(x.id),name(boost::move(x.name)),age(x.age),ssn(x.ssn)
{}
employee& operator=(BOOST_COPY_ASSIGN_REF(employee) x)
{
id=x.id;
name=x.name;
age=x.age;
ssn=x.ssn;
return *this;
};
employee& operator=(BOOST_RV_REF(employee) x)
{
id=x.id;
name=boost::move(x.name);
age=x.age;
ssn=x.ssn;
return *this;
}
bool operator==(const employee& x)const
{
return id==x.id&&name==x.name&&age==x.age;
@ -62,6 +90,9 @@ struct employee
os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
return os;
}
private:
BOOST_COPYABLE_AND_MOVABLE(employee)
};
struct name{};

View File

@ -47,10 +47,11 @@ void test_capacity()
BOOST_TEST(ss.size()==10);
BOOST_TEST(ss.size()<=ss.max_size());
ss.resize(20);
ss.resize(20,666);
BOOST_TEST(ss.size()==20);
BOOST_TEST(ss.back()==666);
ss.resize(5);
ss.resize(5,10);
BOOST_TEST(ss.size()==5);
ss.resize(4);
@ -63,11 +64,16 @@ void test_capacity()
BOOST_TEST(rs.size()<=rs.max_size());
BOOST_TEST(rs.size()<=rs.capacity());
rs.resize(20);
rs.resize(20,666);
BOOST_TEST(rs.size()==20);
BOOST_TEST(rs.back()==666);
BOOST_TEST(rs.size()<=rs.capacity());
unsigned int c=rs.capacity();
rs.resize(10,20);
BOOST_TEST(rs.size()==10);
BOOST_TEST(rs.capacity()==c);
rs.resize(5);
BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==c);
@ -80,4 +86,12 @@ void test_capacity()
rs.reserve(99);
BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==c);
rs.shrink_to_fit();
BOOST_TEST(rs.size()==5);
BOOST_TEST(rs.capacity()==rs.size());
rs.clear();
rs.shrink_to_fit();
BOOST_TEST(rs.capacity()==0);
}

View File

@ -12,6 +12,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <algorithm>
#include <boost/move/utility.hpp>
#include <list>
#include <numeric>
#include <vector>
@ -30,6 +31,13 @@ using namespace boost::multi_index;
#pragma parse_func_templ off
#endif
typedef multi_index_container<int> copyable_and_movable;
struct holder
{
copyable_and_movable c;
};
template<typename Sequence>
static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
{
@ -39,10 +47,16 @@ static void test_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
std::size_t sa=sizeof(a)/sizeof(a[0]);
s.assign(&a[0],&a[sa]);
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
s.assign((const int*)(&a[0]),(const int*)(&a[sa]));
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
s.assign({0,1,2,3,4,5});
#else
s.assign(&a[0],&a[sa]);
#endif
BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
@ -78,6 +92,16 @@ static void test_integral_assign(BOOST_EXPLICIT_TEMPLATE_TYPE(Sequence))
BOOST_TEST(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60);
}
employee_set produce_employee_set()
{
employee_set es;
es.insert(employee(0,"Petr",60,2837));
es.insert(employee(1,"Jiri",25,2143));
es.insert(employee(2,"Radka",40,4875));
es.insert(employee(3,"Milan",38,3474));
return es;
}
void test_copy_assignment()
{
employee_set es;
@ -113,7 +137,7 @@ void test_copy_assignment()
BOOST_TEST(es4==es2);
employee_set es5;
employee_set es5=employee_set(employee_set::ctor_args_list());
employee_set_by_age& i2=get<age>(es5);
i2=get<2>(es2);
@ -131,22 +155,75 @@ void test_copy_assignment()
BOOST_TEST(i5==get<5>(es2));
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
employee_set es8({{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102}});
employee_set es9;
es9={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es8.size()==3);
BOOST_TEST(es9==es8);
es9.clear();
get<0>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<0>(es9)={{0,"Rose",40,4512},{2,"Jo",25,7102},{1,"Mary",38,3345}};
BOOST_TEST(es9==es8);
es9.clear();
get<1>(es9)={{1,"Mary",38,3345},{0,"Rose",40,4512},{2,"Jo",25,7102},
{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<2>(es9)={{2,"Jo",25,7102},{0,"Rose",40,4512},{1,"Mary",38,3345}};
BOOST_TEST(es9==es8);
es9.clear();
get<3>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{1,"Mary",38,3345},
{2,"Jo",25,7102}};
BOOST_TEST(es9==es8);
es9.clear();
get<4>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512}};
BOOST_TEST(es9==es8);
es9.clear();
get<5>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512},
{2,"Jo",25,7102}};
BOOST_TEST(es9==es8);
#endif
employee_set es10(produce_employee_set()),es11(produce_employee_set());
BOOST_TEST(es10==es11);
employee_set es12(boost::move(es10));
BOOST_TEST(es10.empty());
BOOST_TEST(es11==es12);
es10=boost::move(es12);
BOOST_TEST(es12.empty());
BOOST_TEST(es11==es10);
std::list<employee> l;
l.push_back(employee(3,"Anna",31,5388));
l.push_back(employee(1,"Rachel",27,9012));
l.push_back(employee(2,"Agatha",40,1520));
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
employee_set es8;
es8.insert(l.begin(),l.end());
employee_set es13;
es13.insert(l.begin(),l.end());
#else
employee_set es8(l.begin(),l.end());
employee_set es13(l.begin(),l.end());
#endif
l.sort();
BOOST_TEST(es8.size()==l.size()&&
std::equal(es8.begin(),es8.end(),l.begin()));
BOOST_TEST(es13.size()==l.size()&&
std::equal(es13.begin(),es13.end(),l.begin()));
/* MSVC++ 6.0 chokes on test_assign without this explicit instantiation */
multi_index_container<int,indexed_by<sequenced<> > > s1;
@ -158,4 +235,11 @@ void test_copy_assignment()
test_assign<multi_index_container<int,indexed_by<random_access<> > > >();
test_integral_assign<
multi_index_container<int,indexed_by<random_access<> > > >();
/* Testcase for problem described at http://www.boost.org/doc/html/move/
* emulation_limitations.html#move.emulation_limitations.assignment_operator
*/
holder h((holder()));
h=holder();
}

View File

@ -13,6 +13,7 @@
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
#include <boost/detail/lightweight_test.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/move/core.hpp>
#include <boost/next_prior.hpp>
#include <boost/shared_ptr.hpp>
#include <iterator>
@ -22,6 +23,22 @@
using namespace boost::multi_index;
struct non_copyable_int
{
explicit non_copyable_int(int n_):n(n_){}
non_copyable_int(BOOST_RV_REF(non_copyable_int) x):n(x.n){x.n=0;}
non_copyable_int& operator=(BOOST_RV_REF(non_copyable_int) x)
{
n=x.n;
x.n=0;
return *this;
}
int n;
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable_int)
};
class always_one
{
public:
@ -115,13 +132,15 @@ void test_modifiers()
employee_set_randomly& i5=get<randomly>(es);
es.insert(employee(0,"Joe",31,1123));
BOOST_TEST(es.insert(employee(0,"Joe",31,1123)).second==false);
BOOST_TEST(es.emplace(0,"Joe",31,1123).second==false);
BOOST_TEST(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i2.insert(employee(1,"Victor",5,1123)).second==false);
BOOST_TEST(i2.emplace_hint(i2.end(),1,"Victor",5,1123)->name!="Victor");
BOOST_TEST(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second
==false);
BOOST_TEST(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false);
BOOST_TEST(i5.emplace_front(1,"Victor",5,1123).second==false);
BOOST_TEST(i5.emplace_back(1,"Victor",5,1123).second==false);
employee_set_by_name::iterator it1=i1.find("Joe");
i1.insert(it1,employee(1,"Joe Jr.",5,2563));
@ -156,17 +175,18 @@ void test_modifiers()
i5.erase(i5.begin(),i5.end());
BOOST_TEST(es.size()==0&&i3.size()==0);
es.insert(employee(0,"Joe",31,1123));
i5.emplace(i5.end(),0,"Joe",31,1123);
BOOST_TEST(i1.erase(i1.begin())==i1.end());
BOOST_TEST(i1.size()==0);
es.insert(employee(0,"Joe",31,1123));
es.insert(employee(1,"Jack",31,5032));
BOOST_TEST(i2.erase(31)==2);
i1.emplace(0,"Joe",31,1123);
i3.emplace(i3.begin(),1,"Jack",31,5032);
i4.emplace_hint(i4.end(),2,"James",31,3847);
BOOST_TEST(i2.erase(31)==3);
BOOST_TEST(i2.size()==0);
i3.push_front(employee(1,"Jack",31,5032));
i3.push_back(employee(0,"Joe",31,1123));
i3.emplace_front(1,"Jack",31,5032);
i3.emplace_back(0,"Joe",31,1123);
BOOST_TEST(i3.front()==employee(1,"Jack",31,5032));
BOOST_TEST(i3.back()==employee(0,"Joe",31,1123));
@ -206,12 +226,22 @@ void test_modifiers()
i1.insert(ve.begin(),ve.end());
BOOST_TEST(i2.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i1.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i2.size()==5);
#endif
BOOST_TEST(i2.erase(i2.begin(),i2.end())==i2.end());
BOOST_TEST(es.size()==0);
i2.insert(ve.begin(),ve.end());
BOOST_TEST(i3.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i2.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i3.size()==5);
#endif
BOOST_TEST(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012));
BOOST_TEST(i3.erase(i3.begin(),i3.end())==i3.end());
BOOST_TEST(es.size()==0);
@ -219,6 +249,12 @@ void test_modifiers()
i3.insert(i3.end(),ve.begin(),ve.end());
BOOST_TEST(es.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i3.insert(i3.begin(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i3.front().name=="Vanessa");
BOOST_TEST(i4.size()==5);
#endif
BOOST_TEST(i4.erase(9012)==1);
i4.erase(i4.begin());
BOOST_TEST(i4.erase(i4.begin(),i4.end())==i4.end());
@ -232,6 +268,12 @@ void test_modifiers()
i5.insert(i5.begin(),ve.begin(),ve.end());
BOOST_TEST(i1.size()==3);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
i5.insert(i5.end(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
BOOST_TEST(i5.back().name=="Penelope");
BOOST_TEST(i1.size()==5);
#endif
BOOST_TEST(es.erase(es.begin(),es.end())==es.end());
BOOST_TEST(i2.size()==0);
@ -324,6 +366,52 @@ void test_modifiers()
es2.clear();
BOOST_TEST(es2.size()==0);
/* non-copyable elements */
multi_index_container<
non_copyable_int,
indexed_by<
ordered_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
hashed_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
sequenced<>,
random_access<>
>
> ncic,ncic2;
ncic.emplace(1);
get<1>(ncic).emplace(1);
get<2>(ncic).emplace_back(1);
get<3>(ncic).emplace_back(1);
non_copyable_int nci(1);
ncic.insert(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<1>(ncic).insert(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<2>(ncic).push_back(boost::move(nci));
BOOST_TEST(nci.n==0);
nci.n=1;
get<3>(ncic).push_back(boost::move(nci));
BOOST_TEST(nci.n==0);
std::vector<int> vi(4,1);
const std::vector<int>& cvi=vi;
ncic.insert(vi.begin(),vi.end());
ncic.insert(cvi.begin(),cvi.end());
get<2>(ncic).insert(get<2>(ncic).begin(),vi.begin(),vi.end());
get<2>(ncic).insert(get<2>(ncic).begin(),cvi.begin(),cvi.end());
BOOST_TEST(ncic.count(1)==24);
ncic.swap(ncic2);
BOOST_TEST(ncic.empty());
BOOST_TEST(ncic2.count(1)==24);
/* testcase for problem reported at
* http://lists.boost.org/boost-users/2006/12/24215.php
*/

View File

@ -78,6 +78,8 @@ void test_update()
project<randomly>(es,get<age>(es).find(57));
BOOST_TEST(es.replace(it,*it));
BOOST_TEST(i.replace(it1,*it1));
BOOST_TEST(r.replace(it2,*it2));
BOOST_TEST(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0);
BOOST_TEST(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32);
BOOST_TEST(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name==